1 /*
2 * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "fs_verity_generator.h"
16
17 namespace OHOS {
18 namespace SignatureTools {
19 const FsVerityHashAlgorithm FS_SHA256(1, "SHA-256", 256 / 8);
20 const FsVerityHashAlgorithm FS_SHA512(2, "SHA-512", 512 / 8);
21 const int8_t FsVerityGenerator::LOG_2_OF_FSVERITY_HASH_PAGE_SIZE = 12;
22 const FsVerityHashAlgorithm FsVerityGenerator::FS_VERITY_HASH_ALGORITHM = FS_SHA256;
23
GenerateMerkleTree(std::istream& inputStream, long size, const FsVerityHashAlgorithm& fsVerityHashAlgorithm)24 MerkleTree* FsVerityGenerator::GenerateMerkleTree(std::istream& inputStream, long size,
25 const FsVerityHashAlgorithm& fsVerityHashAlgorithm)
26 {
27 std::unique_ptr<MerkleTreeBuilder>builder = std::make_unique<MerkleTreeBuilder>(MerkleTreeBuilder());
28 return builder->GenerateMerkleTree(inputStream, size, fsVerityHashAlgorithm);
29 }
30
GenerateFsVerityDigest(std::istream& inputStream, long size, long fsvTreeOffset)31 bool FsVerityGenerator::GenerateFsVerityDigest(std::istream& inputStream, long size, long fsvTreeOffset)
32 {
33 std::vector<int8_t> emptyVector;
34 MerkleTree* merkleTree = nullptr;
35 if (size == 0) {
36 merkleTree = new MerkleTree(emptyVector, emptyVector, FS_SHA256);
37 } else {
38 merkleTree = GenerateMerkleTree(inputStream, size, FS_SHA256);
39 }
40 if (merkleTree == nullptr) {
41 return false;
42 }
43 int flags = fsvTreeOffset == 0 ? 0 : FsVerityDescriptor::FLAG_STORE_MERKLE_TREE_OFFSET;
44 std::shared_ptr<MerkleTree> merkleTree_ptr(merkleTree);
45 // sign size is 0, cs version is 0
46 std::unique_ptr<FsVerityDescriptor::Builder> builder = std::make_unique<FsVerityDescriptor::Builder>();
47 builder->SetFileSize(size)
48 .SetHashAlgorithm(FS_SHA256.GetId())
49 .SetLog2BlockSize(LOG_2_OF_FSVERITY_HASH_PAGE_SIZE)
50 .SetSaltSize((uint8_t)GetSaltSize())
51 .SetSalt(salt)
52 .SetRawRootHash(merkleTree_ptr->rootHash)
53 .SetFlags(flags)
54 .SetMerkleTreeOffset(fsvTreeOffset);
55 std::vector<int8_t> fsVerityDescriptor;
56 builder->Build().GetByteForGenerateDigest(fsVerityDescriptor);
57 std::vector<int8_t> digest;
58 DigestUtils digestUtils(HASH_SHA256);
59 std::stringstream ss;
60 for (const auto& elem : fsVerityDescriptor) {
61 ss << elem;
62 }
63 digestUtils.AddData(ss.str());
64 std::string result = digestUtils.Result(DigestUtils::Type::BINARY);
65 for (int i = 0; i < result.size(); i++) {
66 digest.push_back(result[i]);
67 }
68 FsVerityDigest::GetFsVerityDigest(FS_SHA256.GetId(), digest, fsVerityDigest);
69 treeBytes = merkleTree_ptr->tree;
70 rootHash = merkleTree_ptr->rootHash;
71 return true;
72 }
73 } // namespace SignatureTools
74 } // namespace OHOS