• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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