• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_descriptor.h"
16 
17 namespace OHOS {
18 namespace SignatureTools {
FsVerityDescriptor()19 FsVerityDescriptor::FsVerityDescriptor()
20 {}
21 
FromByteArray(std::vector<int8_t> & bytes)22 FsVerityDescriptor FsVerityDescriptor::FromByteArray(std::vector<int8_t>& bytes)
23 {
24     std::unique_ptr<ByteBuffer> bf = std::make_unique<ByteBuffer>(ByteBuffer(bytes.size()));
25     bf->PutData(bytes.data(), bytes.size());
26     // after put, rewind is mandatory before get
27     bf->Flip();
28     std::unique_ptr<FsVerityDescriptor::Builder> builder =
29         std::make_unique<FsVerityDescriptor::Builder>(FsVerityDescriptor::Builder());
30     int8_t inFsVersion;
31     bf->GetInt8(inFsVersion);
32     if (FsVerityDescriptor::VERSION != inFsVersion) {
33         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
34                             "The FS descriptor version of FsVerityDescriptor is incorrect");
35         return builder->Build();
36     }
37     int8_t inFsHashAlgorithm;
38     bf->GetInt8(inFsHashAlgorithm);
39     int8_t inLog2BlockSize;
40     bf->GetInt8(inLog2BlockSize);
41     builder->SetVersion(inFsVersion).SetHashAlgorithm(inFsHashAlgorithm).SetLog2BlockSize(inLog2BlockSize);
42     int8_t inSaltSize;
43     bf->GetInt8(inSaltSize);
44     int32_t inSignSize;
45     bf->GetInt32(inSignSize);
46     int64_t inDataSize;
47     bf->GetInt64(inDataSize);
48     char inRootHashArr[FsVerityDescriptor::ROOT_HASH_FILED_SIZE];
49     bf->GetData(inRootHashArr, FsVerityDescriptor::ROOT_HASH_FILED_SIZE);
50     std::vector<int8_t> inRootHash(inRootHashArr, inRootHashArr + FsVerityDescriptor::ROOT_HASH_FILED_SIZE);
51     builder->SetSaltSize(inSaltSize).SetSignSize(inSignSize).SetFileSize(inDataSize).SetRawRootHash(inRootHash);
52     char inSaltArr[FsVerityDescriptor::SALT_SIZE];
53     bf->GetData(inSaltArr, FsVerityDescriptor::SALT_SIZE);
54     std::vector<int8_t> inSalt(inSaltArr, inSaltArr + FsVerityDescriptor::SALT_SIZE);
55     int32_t inFlags;
56     bf->GetInt32(inFlags);
57     bf->SetPosition(bf->GetPosition() + RESERVED_SIZE_AFTER_FLAGS);
58     int64_t inTreeOffset;
59     bf->GetInt64(inTreeOffset);
60     if (inTreeOffset % PAGE_SIZE_4K != 0) {
61         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
62                             "The offset of merkle tree of FsVerityDescriptor is incorrect");
63         return builder->Build();
64     }
65     int8_t reserve[FsVerityDescriptor::RESERVED_SIZE_AFTER_TREE_OFFSET];
66     bf->GetByte(reserve, sizeof(reserve));
67     int8_t inCsVersion;
68     bf->GetInt8(inCsVersion);
69     builder->SetSalt(inSalt).SetFlags(inFlags).SetMerkleTreeOffset(inTreeOffset).SetCsVersion(inCsVersion);
70     return builder->Build();
71 }
72 
ToByteArray(std::vector<int8_t> & ret)73 void FsVerityDescriptor::ToByteArray(std::vector<int8_t> &ret)
74 {
75     std::unique_ptr<ByteBuffer> buffer = std::make_unique<ByteBuffer>(ByteBuffer(DESCRIPTOR_SIZE));
76     buffer->PutByte(VERSION);
77     buffer->PutByte(hashAlgorithm);
78     buffer->PutByte(log2BlockSize);
79     if (saltSize > SALT_SIZE) {
80         PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "Salt is too long");
81         ret = std::vector<int8_t>();
82         return;
83     }
84     buffer->PutByte(saltSize);
85     buffer->PutInt32(signSize);
86     buffer->PutInt64(fileSize);
87     WriteBytesWithSize(buffer.get(), rawRootHash, ROOT_HASH_FILED_SIZE);
88     WriteBytesWithSize(buffer.get(), salt, SALT_SIZE);
89     buffer->PutInt32(flags);
90     std::vector<int8_t> emptyVector;
91     WriteBytesWithSize(buffer.get(), emptyVector, RESERVED_SIZE_AFTER_FLAGS);
92     buffer->PutInt64(merkleTreeOffset);
93     WriteBytesWithSize(buffer.get(), emptyVector, RESERVED_SIZE_AFTER_TREE_OFFSET);
94     buffer->PutByte(csVersion);
95     buffer->Flip();
96     char dataArr[DESCRIPTOR_SIZE] = { 0 };
97     buffer->GetData(dataArr, DESCRIPTOR_SIZE);
98     ret = std::vector<int8_t>(dataArr, dataArr + DESCRIPTOR_SIZE);
99     return;
100 }
101 
GetByteForGenerateDigest(std::vector<int8_t> & ret)102 void FsVerityDescriptor::GetByteForGenerateDigest(std::vector<int8_t> &ret)
103 {
104     std::unique_ptr<ByteBuffer> buffer = std::make_unique<ByteBuffer>(ByteBuffer(DESCRIPTOR_SIZE));
105     buffer->PutByte(CODE_SIGN_VERSION);
106     buffer->PutByte(hashAlgorithm);
107     buffer->PutByte(log2BlockSize);
108     if (saltSize > SALT_SIZE) {
109         PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "Salt is too long");
110         ret = std::vector<int8_t>();
111         return;
112     }
113     buffer->PutByte(saltSize);
114     buffer->PutInt32(0);
115     buffer->PutInt64(fileSize);
116     WriteBytesWithSize(buffer.get(), rawRootHash, ROOT_HASH_FILED_SIZE);
117     WriteBytesWithSize(buffer.get(), salt, SALT_SIZE);
118     buffer->PutInt32(flags);
119     std::vector<int8_t> emptyVector;
120     WriteBytesWithSize(buffer.get(), emptyVector, RESERVED_SIZE_AFTER_FLAGS);
121     buffer->PutInt64(merkleTreeOffset);
122     buffer->Flip();
123     char dataArr[DESCRIPTOR_SIZE] = { 0 };
124     buffer->GetData(dataArr, DESCRIPTOR_SIZE);
125     ret = std::vector<int8_t>(dataArr, dataArr + DESCRIPTOR_SIZE);
126     return;
127 }
128 
WriteBytesWithSize(ByteBuffer * buffer,std::vector<int8_t> & src,int size)129 void FsVerityDescriptor::WriteBytesWithSize(ByteBuffer* buffer, std::vector<int8_t>& src, int size)
130 {
131     int pos = buffer->GetPosition();
132     if (!src.empty()) {
133         if (src.size() > size) {
134             buffer->PutData(0, src.data(), src.size());
135         } else {
136             buffer->PutData(src.data(), src.size());
137         }
138     }
139     buffer->SetPosition(pos + size);
140 }
141 } // namespace SignatureTools
142 } // namespace OHOS