1 /*
2 * Copyright (c) 2025-2025 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 uint8_t ELF_CODE_SIGN_VERSION = 0x3;
23 const FsVerityHashAlgorithm FsVerityGenerator::FS_VERITY_HASH_ALGORITHM = FS_SHA256;
24
GenerateMerkleTree(std::istream & inputStream,long size,const FsVerityHashAlgorithm & fsVerityHashAlgorithm)25 MerkleTree* FsVerityGenerator::GenerateMerkleTree(std::istream& inputStream, long size,
26 const FsVerityHashAlgorithm& fsVerityHashAlgorithm)
27 {
28 std::unique_ptr<MerkleTreeBuilder>builder = std::make_unique<MerkleTreeBuilder>(MerkleTreeBuilder());
29 builder->SetCsOffset(csOffset);
30 return builder->GenerateMerkleTree(inputStream, size, fsVerityHashAlgorithm);
31 }
32
GenerateFsVerityDigest(std::istream & inputStream,long size,int flags)33 bool FsVerityGenerator::GenerateFsVerityDigest(std::istream& inputStream, long size, int flags)
34 {
35 MerkleTree* merkleTree = GenerateMerkleTree(inputStream, size, FS_SHA256);
36 if (merkleTree == nullptr) {
37 return false;
38 }
39 std::shared_ptr<MerkleTree> merkleTree_ptr(merkleTree);
40 // sign size is 0,
41 std::unique_ptr<FsVerityDescriptor::Builder> builder = std::make_unique<FsVerityDescriptor::Builder>();
42 builder->SetFileSize(size)
43 .SetHashAlgorithm(FS_SHA256.GetId())
44 .SetLog2BlockSize(LOG_2_OF_FSVERITY_HASH_PAGE_SIZE)
45 .SetSaltSize((uint8_t)GetSaltSize())
46 .SetSalt(salt)
47 .SetRawRootHash(merkleTree_ptr->rootHash)
48 .SetFlags(flags)
49 .SetCsVersion(ELF_CODE_SIGN_VERSION);
50 std::vector<int8_t> fsVerityDescriptor;
51 builder->Build().GetByteForGenerateDigest(fsVerityDescriptor);
52 DigestUtils digestUtils(HASH_SHA256);
53 std::stringstream ss;
54 for (const auto& elem : fsVerityDescriptor) {
55 ss << elem;
56 }
57 digestUtils.AddData(ss.str());
58 std::string result = digestUtils.Result(DigestUtils::Type::BINARY);
59 for (long i = 0; i < result.size(); i++) {
60 descriptorDigest.push_back(result[i]);
61 }
62 FsVerityDigest::GetFsVerityDigest(FS_SHA256.GetId(), descriptorDigest, fsVerityDigest);
63 treeBytes = merkleTree_ptr->tree;
64 rootHash = merkleTree_ptr->rootHash;
65 return true;
66 }
67 } // namespace SignatureTools
68 } // namespace OHOS