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 16#include "elf_sign_block.h" 17 18namespace OHOS { 19namespace SignatureTools { 20 21ElfSignBlock::ElfSignBlock() 22{ 23 type = MERKLE_TREE_INLINED; 24} 25 26ElfSignBlock::ElfSignBlock(int32_t paddingSize, const std::vector<int8_t> &merkleTreeData, 27 const FsVerityDescriptorWithSign &descriptorWithSign) 28{ 29 std::vector<int8_t> inMerkleTreeData; 30 if (!merkleTreeData.empty()) { 31 inMerkleTreeData = merkleTreeData; 32 } 33 treeLength = paddingSize + inMerkleTreeData.size(); 34 merkleTreeWithPadding.resize(treeLength); 35 std::copy(inMerkleTreeData.begin(), inMerkleTreeData.end(), merkleTreeWithPadding.begin() + paddingSize); 36 this->descriptorWithSign = descriptorWithSign; 37} 38 39int32_t ElfSignBlock::Size() 40{ 41 int tmpVariable = 2; 42 return FsVerityDescriptorWithSign::INTEGER_BYTES * tmpVariable 43 + merkleTreeWithPadding.size() + descriptorWithSign.Size(); 44} 45 46std::vector<int8_t>& ElfSignBlock::GetMerkleTreeWithPadding() 47{ 48 return merkleTreeWithPadding; 49} 50 51int64_t ElfSignBlock::GetDataSize() 52{ 53 return descriptorWithSign.GetFsVerityDescriptor().GetFileSize(); 54} 55 56int64_t ElfSignBlock::GetTreeOffset() 57{ 58 return descriptorWithSign.GetFsVerityDescriptor().GetMerkleTreeOffset(); 59} 60 61std::vector<int8_t>& ElfSignBlock::GetSignature() 62{ 63 return descriptorWithSign.GetSignature(); 64} 65 66void ElfSignBlock::ToByteArray(std::vector<int8_t>& ret) 67{ 68 std::unique_ptr<ByteBuffer> bf = std::make_unique<ByteBuffer>(Size()); 69 bf->PutInt32(type); 70 bf->PutInt32(merkleTreeWithPadding.size()); 71 bf->PutData(merkleTreeWithPadding.data(), merkleTreeWithPadding.size()); 72 std::vector<int8_t> descriptorWithSignArr; 73 descriptorWithSign.ToByteArray(descriptorWithSignArr); 74 bf->PutData(descriptorWithSignArr.data(), descriptorWithSignArr.size()); 75 ret = std::vector<int8_t>(bf->GetBufferPtr(), bf->GetBufferPtr() + bf->GetLimit()); 76} 77 78bool ElfSignBlock::FromByteArray(std::vector<int8_t>& bytes, ElfSignBlock& elfSignBlock) 79{ 80 std::unique_ptr<ByteBuffer> bf = std::make_unique<ByteBuffer>(bytes.size()); 81 bf->PutData(bytes.data(), bytes.size()); 82 bf->Flip(); 83 int32_t inTreeType = 0; 84 bf->GetInt32(inTreeType); 85 if (MERKLE_TREE_INLINED != inTreeType) { 86 PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, 87 "The merkle tree type of elf signature block is incorrect"); 88 return false; 89 } 90 int32_t inTreeLength = 0; 91 bf->GetInt32(inTreeLength); 92 std::vector<int8_t> treeWithPadding(inTreeLength); 93 bf->GetByte(treeWithPadding.data(), treeWithPadding.size()); 94 int32_t inFsdType = 0; 95 bf->GetInt32(inFsdType); 96 if (FsVerityDescriptor::FS_VERITY_DESCRIPTOR_TYPE != inFsdType) { 97 PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, 98 "The FS descriptor type of elf signature block is incorrect"); 99 return false; 100 } 101 int32_t inFsdLength = 0; 102 int tmpVariable = 2; 103 bf->GetInt32(inFsdLength); 104 if (bytes.size() != FsVerityDescriptorWithSign::INTEGER_BYTES * tmpVariable + inTreeLength + 105 FsVerityDescriptorWithSign::INTEGER_BYTES * tmpVariable + inFsdLength) { 106 PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, 107 "The signature length of the elf signature block is incorrect"); 108 return false; 109 } 110 std::vector<int8_t> fsdArray(FsVerityDescriptor::DESCRIPTOR_SIZE); 111 bf->GetByte(fsdArray.data(), fsdArray.size()); 112 FsVerityDescriptor fsd = FsVerityDescriptor::FromByteArray(fsdArray); 113 if (inFsdLength != fsd.GetSignSize() + FsVerityDescriptor::DESCRIPTOR_SIZE) { 114 PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, 115 "The signed size of the elf signature block is incorrect"); 116 return false; 117 } 118 std::vector<int8_t> inSignature(inFsdLength - FsVerityDescriptor::DESCRIPTOR_SIZE); 119 bf->GetByte(inSignature.data(), inSignature.size()); 120 FsVerityDescriptorWithSign fsVerityDescriptorWithSign(inFsdType, inFsdLength, fsd, inSignature); 121 elfSignBlock.type = inTreeType; 122 elfSignBlock.treeLength = inTreeLength; 123 elfSignBlock.merkleTreeWithPadding = treeWithPadding; 124 elfSignBlock.descriptorWithSign = fsVerityDescriptorWithSign; 125 return true; 126} 127 128int32_t ElfSignBlock::ComputeMerkleTreePaddingLength(int64_t signBlockOffset) 129{ 130 int tmpVariable = 2; 131 return (int32_t)(PAGE_SIZE_4K - (signBlockOffset + FsVerityDescriptorWithSign::INTEGER_BYTES * tmpVariable) 132 % PAGE_SIZE_4K) % PAGE_SIZE_4K; 133} 134 135} 136}