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