18e920a95Sopenharmony_ci/* 28e920a95Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 38e920a95Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48e920a95Sopenharmony_ci * you may not use this file except in compliance with the License. 58e920a95Sopenharmony_ci * You may obtain a copy of the License at 68e920a95Sopenharmony_ci * 78e920a95Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88e920a95Sopenharmony_ci * 98e920a95Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108e920a95Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118e920a95Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128e920a95Sopenharmony_ci * See the License for the specific language governing permissions and 138e920a95Sopenharmony_ci * limitations under the License. 148e920a95Sopenharmony_ci */ 158e920a95Sopenharmony_ci 168e920a95Sopenharmony_ci#ifndef CODE_SIGN_BLOCK_H 178e920a95Sopenharmony_ci#define CODE_SIGN_BLOCK_H 188e920a95Sopenharmony_ci 198e920a95Sopenharmony_ci#include <cstdint> 208e920a95Sopenharmony_ci#include <cstdlib> 218e920a95Sopenharmony_ci#include <string> 228e920a95Sopenharmony_ci#include <vector> 238e920a95Sopenharmony_ci#include <unordered_map> 248e920a95Sopenharmony_ci#include <mutex> 258e920a95Sopenharmony_ci#include <linux/fsverity.h> 268e920a95Sopenharmony_ci#include "code_sign_utils.h" 278e920a95Sopenharmony_ci#include "interfaces/hap_verify.h" 288e920a95Sopenharmony_ci#include "interfaces/hap_verify_result.h" 298e920a95Sopenharmony_ci 308e920a95Sopenharmony_cinamespace OHOS { 318e920a95Sopenharmony_cinamespace Security { 328e920a95Sopenharmony_cinamespace CodeSign { 338e920a95Sopenharmony_ci 348e920a95Sopenharmony_ci#pragma pack(push, 1) 358e920a95Sopenharmony_citypedef struct { 368e920a95Sopenharmony_ci uint32_t type; 378e920a95Sopenharmony_ci uint32_t size; 388e920a95Sopenharmony_ci uint32_t offset; 398e920a95Sopenharmony_ci} PropertyBlobHeader; 408e920a95Sopenharmony_ci 418e920a95Sopenharmony_citypedef struct { 428e920a95Sopenharmony_ci uint64_t magic; 438e920a95Sopenharmony_ci uint32_t version; 448e920a95Sopenharmony_ci uint32_t blockSize; 458e920a95Sopenharmony_ci uint32_t segmentNum; 468e920a95Sopenharmony_ci uint32_t flags; 478e920a95Sopenharmony_ci uint8_t reserved[8]; 488e920a95Sopenharmony_ci} CodeSignBlockHeader; 498e920a95Sopenharmony_ci 508e920a95Sopenharmony_citypedef struct { 518e920a95Sopenharmony_ci uint32_t type; 528e920a95Sopenharmony_ci uint32_t offset; 538e920a95Sopenharmony_ci uint32_t size; 548e920a95Sopenharmony_ci} SegmentHeader; 558e920a95Sopenharmony_ci 568e920a95Sopenharmony_citypedef struct { 578e920a95Sopenharmony_ci uint32_t magic; 588e920a95Sopenharmony_ci uint8_t version; 598e920a95Sopenharmony_ci uint8_t hashAlgorithm; 608e920a95Sopenharmony_ci uint8_t logBlockSize; 618e920a95Sopenharmony_ci uint8_t reserved[1]; 628e920a95Sopenharmony_ci} FsVerityInfo; 638e920a95Sopenharmony_ci 648e920a95Sopenharmony_citypedef struct { 658e920a95Sopenharmony_ci uint32_t type; 668e920a95Sopenharmony_ci uint32_t size; 678e920a95Sopenharmony_ci} ExtensionHeader; 688e920a95Sopenharmony_ci 698e920a95Sopenharmony_citypedef struct { 708e920a95Sopenharmony_ci uint64_t treeSize; 718e920a95Sopenharmony_ci uint64_t treeOffset; 728e920a95Sopenharmony_ci uint8_t rootHash[64]; 738e920a95Sopenharmony_ci} MerkleTreeExtension; 748e920a95Sopenharmony_ci 758e920a95Sopenharmony_citypedef struct { 768e920a95Sopenharmony_ci uint64_t mapOffset; 778e920a95Sopenharmony_ci uint64_t mapSize; 788e920a95Sopenharmony_ci uint8_t unitSize; 798e920a95Sopenharmony_ci uint8_t reversed[3]; 808e920a95Sopenharmony_ci uint32_t sign_size; 818e920a95Sopenharmony_ci uint8_t signature[0]; 828e920a95Sopenharmony_ci} PageInfoExtension; 838e920a95Sopenharmony_ci 848e920a95Sopenharmony_citypedef struct { 858e920a95Sopenharmony_ci uint32_t saltSize; 868e920a95Sopenharmony_ci uint32_t signSize; 878e920a95Sopenharmony_ci uint32_t flags; 888e920a95Sopenharmony_ci uint64_t dataSize; 898e920a95Sopenharmony_ci uint8_t salt[32]; 908e920a95Sopenharmony_ci uint32_t extensionNum; 918e920a95Sopenharmony_ci uint32_t extensionOffset; 928e920a95Sopenharmony_ci uint8_t signature[0]; 938e920a95Sopenharmony_ci} SignInfo; 948e920a95Sopenharmony_ci 958e920a95Sopenharmony_citypedef struct { 968e920a95Sopenharmony_ci uint32_t magic; 978e920a95Sopenharmony_ci SignInfo signInfo; 988e920a95Sopenharmony_ci} HapSignInfo; 998e920a95Sopenharmony_ci 1008e920a95Sopenharmony_citypedef struct { 1018e920a95Sopenharmony_ci uint32_t fileNameOffset; 1028e920a95Sopenharmony_ci uint32_t fileNameSize; 1038e920a95Sopenharmony_ci uint32_t signOffset; 1048e920a95Sopenharmony_ci uint32_t signSize; 1058e920a95Sopenharmony_ci} EntryInfo; 1068e920a95Sopenharmony_ci 1078e920a95Sopenharmony_citypedef struct { 1088e920a95Sopenharmony_ci uint32_t magic; 1098e920a95Sopenharmony_ci uint32_t length; 1108e920a95Sopenharmony_ci uint32_t sectionNum; 1118e920a95Sopenharmony_ci EntryInfo info[0]; 1128e920a95Sopenharmony_ci} NativeLibSignInfo; 1138e920a95Sopenharmony_ci#pragma pack(pop) 1148e920a95Sopenharmony_ci 1158e920a95Sopenharmony_ciusing SignMap = std::unordered_map<std::string, uintptr_t>; 1168e920a95Sopenharmony_ciusing ReadBuffer = const char *; 1178e920a95Sopenharmony_ci#define CONST_STATIC_CAST(type, ptr) static_cast<const type *>(static_cast<const void *>(ptr)) 1188e920a95Sopenharmony_ci 1198e920a95Sopenharmony_ciclass CodeSignBlock { 1208e920a95Sopenharmony_cipublic: 1218e920a95Sopenharmony_ci CodeSignBlock(); 1228e920a95Sopenharmony_ci ~CodeSignBlock(); 1238e920a95Sopenharmony_ci 1248e920a95Sopenharmony_ci static constexpr uint64_t CSB_BLOCK_HEADER_MAGIC = 0xE046C8C65389FCCD; 1258e920a95Sopenharmony_ci static constexpr uint32_t CSB_FSVERITY_MAGIC = 0x1E3831AB; 1268e920a95Sopenharmony_ci static constexpr uint32_t CSB_HAP_HEADER_MAGIC = 0xC1B5CC66; 1278e920a95Sopenharmony_ci static constexpr uint32_t CSB_SO_HEADER_MAGIC = 0xED2E720; 1288e920a95Sopenharmony_ci static constexpr uint32_t CSB_SIGN_INFO_MERKLE_TREE = 0x1; 1298e920a95Sopenharmony_ci static constexpr uint32_t CSB_SIGN_INFO_RUNTIME_PAGE = 0x2; 1308e920a95Sopenharmony_ci static constexpr uint32_t CSB_EXTENSION_TYPE_MERKLE_TREE = 1; 1318e920a95Sopenharmony_ci static constexpr uint32_t CSB_EXTENSION_TYPE_PAGE_INFO = 2; 1328e920a95Sopenharmony_ci static constexpr uint32_t CSB_SIGN_INFO_MAX_PAGEINFO_UNITSIZE = 7; 1338e920a95Sopenharmony_ci static constexpr uint32_t CSB_EXTENSION_TYPE_PAGE_INFO_VERSION = 2; 1348e920a95Sopenharmony_ci 1358e920a95Sopenharmony_ci int32_t ParseCodeSignBlock(const std::string &realPath, const EntryMap &entryMap, FileType fileType); 1368e920a95Sopenharmony_ci int32_t GetOneFileAndCodeSignInfo(std::string &targetFile, struct code_sign_enable_arg &arg); 1378e920a95Sopenharmony_ci int32_t ProcessExtension(uintptr_t &extensionAddr, const uintptr_t blockAddrEnd, struct code_sign_enable_arg &arg); 1388e920a95Sopenharmony_ci 1398e920a95Sopenharmony_ciprivate: 1408e920a95Sopenharmony_ci int32_t ParseNativeLibSignInfo(const EntryMap &entryMap); 1418e920a95Sopenharmony_ci int32_t ParseHapSignInfo(const std::string &path); 1428e920a95Sopenharmony_ci int32_t ParseCodeSignBlockBaseInfo(ReadBuffer codeSignBlock, uint32_t &blockSize); 1438e920a95Sopenharmony_ci int32_t GetCodeSignBlockBuffer(const std::string &path, ReadBuffer &signBuffer, uint32_t &size); 1448e920a95Sopenharmony_ci 1458e920a95Sopenharmony_ci static constexpr uint32_t CSB_HEADER_VERSION = 1; 1468e920a95Sopenharmony_ci static constexpr uint32_t CSB_HEADER_FLAG_MERKLE_TREE = 0x1; 1478e920a95Sopenharmony_ci static constexpr uint32_t CSB_HEADER_FLAG_SO = 0x2; 1488e920a95Sopenharmony_ci static constexpr uint32_t CSB_FSVERITY_INFO_SEG = 0x1; 1498e920a95Sopenharmony_ci static constexpr uint32_t CSB_HAP_META_SEG = 0x2; 1508e920a95Sopenharmony_ci static constexpr uint32_t CSB_NATIVE_LIB_INFO_SEG = 0x3; 1518e920a95Sopenharmony_ci static constexpr uint32_t CSB_SEGMENT_MAX = 3; 1528e920a95Sopenharmony_ci static constexpr uint32_t CSB_FSVERITY_BLOCK_SIZE = 12; 1538e920a95Sopenharmony_ci 1548e920a95Sopenharmony_ci const CodeSignBlockHeader *GetCodeSignBlockHeader(void) 1558e920a95Sopenharmony_ci { 1568e920a95Sopenharmony_ci return blockHeader_; 1578e920a95Sopenharmony_ci } 1588e920a95Sopenharmony_ci const FsVerityInfo *GetFsVerityInfo(void) 1598e920a95Sopenharmony_ci { 1608e920a95Sopenharmony_ci return fsVerityInfo_; 1618e920a95Sopenharmony_ci } 1628e920a95Sopenharmony_ci const HapSignInfo *GetHapSignInfo(void) 1638e920a95Sopenharmony_ci { 1648e920a95Sopenharmony_ci return hapSignInfo_; 1658e920a95Sopenharmony_ci } 1668e920a95Sopenharmony_ci const NativeLibSignInfo *GetNativeLibSignInfo(void) 1678e920a95Sopenharmony_ci { 1688e920a95Sopenharmony_ci return nativeLibSignInfo_; 1698e920a95Sopenharmony_ci } 1708e920a95Sopenharmony_ci 1718e920a95Sopenharmony_ci int32_t SetCodeSignBlockHeader(const CodeSignBlockHeader *header, uint32_t &blockSize) 1728e920a95Sopenharmony_ci { 1738e920a95Sopenharmony_ci if (header->magic != CSB_BLOCK_HEADER_MAGIC) { 1748e920a95Sopenharmony_ci return CS_ERR_BLOCK_MAGIC; 1758e920a95Sopenharmony_ci } 1768e920a95Sopenharmony_ci if (header->version != CSB_HEADER_VERSION) { 1778e920a95Sopenharmony_ci return CS_ERR_BLOCK_VERSION; 1788e920a95Sopenharmony_ci } 1798e920a95Sopenharmony_ci if ((header->segmentNum > CSB_SEGMENT_MAX) || (header->segmentNum == 0)) { 1808e920a95Sopenharmony_ci return CS_ERR_BLOCK_SEG_NUM; 1818e920a95Sopenharmony_ci } 1828e920a95Sopenharmony_ci if (header->blockSize != blockSize) { 1838e920a95Sopenharmony_ci return CS_ERR_BLOCK_SIZE; 1848e920a95Sopenharmony_ci } 1858e920a95Sopenharmony_ci blockHeader_ = header; 1868e920a95Sopenharmony_ci return CS_SUCCESS; 1878e920a95Sopenharmony_ci } 1888e920a95Sopenharmony_ci 1898e920a95Sopenharmony_ci int32_t SetFsVerityInfo(const FsVerityInfo *info) 1908e920a95Sopenharmony_ci { 1918e920a95Sopenharmony_ci if (info->magic != CSB_FSVERITY_MAGIC) { 1928e920a95Sopenharmony_ci return CS_ERR_FSVERITY_MAGIC; 1938e920a95Sopenharmony_ci } 1948e920a95Sopenharmony_ci if (info->version != 1) { 1958e920a95Sopenharmony_ci return CS_ERR_FSVERITY_VERSION; 1968e920a95Sopenharmony_ci } 1978e920a95Sopenharmony_ci if (info->logBlockSize != CSB_FSVERITY_BLOCK_SIZE) { 1988e920a95Sopenharmony_ci return CS_ERR_FSVERITY_BLOCK_SIZE; 1998e920a95Sopenharmony_ci } 2008e920a95Sopenharmony_ci fsVerityInfo_ = info; 2018e920a95Sopenharmony_ci return CS_SUCCESS; 2028e920a95Sopenharmony_ci } 2038e920a95Sopenharmony_ci 2048e920a95Sopenharmony_ci int32_t SetHapSignInfo(const HapSignInfo *info) 2058e920a95Sopenharmony_ci { 2068e920a95Sopenharmony_ci if (info->magic != CSB_HAP_HEADER_MAGIC) { 2078e920a95Sopenharmony_ci return CS_ERR_HAP_MAGIC; 2088e920a95Sopenharmony_ci } 2098e920a95Sopenharmony_ci const auto signInfo = &info->signInfo; 2108e920a95Sopenharmony_ci if (blockHeader_->flags & CSB_HEADER_FLAG_MERKLE_TREE) { 2118e920a95Sopenharmony_ci if (signInfo->extensionOffset >= blockHeader_->blockSize) { 2128e920a95Sopenharmony_ci return CS_ERR_HAP_EXTERNSION; 2138e920a95Sopenharmony_ci } 2148e920a95Sopenharmony_ci } 2158e920a95Sopenharmony_ci hapSignInfo_ = info; 2168e920a95Sopenharmony_ci return CS_SUCCESS; 2178e920a95Sopenharmony_ci } 2188e920a95Sopenharmony_ci 2198e920a95Sopenharmony_ci int32_t SetNativeLibSignInfo(const NativeLibSignInfo *info) 2208e920a95Sopenharmony_ci { 2218e920a95Sopenharmony_ci if (info->magic != CSB_SO_HEADER_MAGIC) { 2228e920a95Sopenharmony_ci return CS_ERR_SO_MAGIC; 2238e920a95Sopenharmony_ci } 2248e920a95Sopenharmony_ci if ((blockHeader_->flags & CSB_HEADER_FLAG_SO) && !info->sectionNum) { 2258e920a95Sopenharmony_ci return CS_ERR_SO_SECTION_NUM; 2268e920a95Sopenharmony_ci } 2278e920a95Sopenharmony_ci nativeLibSignInfo_ = info; 2288e920a95Sopenharmony_ci return CS_SUCCESS; 2298e920a95Sopenharmony_ci } 2308e920a95Sopenharmony_ci 2318e920a95Sopenharmony_ci int32_t GetOneMapNodeFromSignMap(std::string &fileName, uintptr_t &signInfo) 2328e920a95Sopenharmony_ci { 2338e920a95Sopenharmony_ci std::lock_guard<std::mutex> guard(signMapMutex_); 2348e920a95Sopenharmony_ci if (signMap_.empty()) { 2358e920a95Sopenharmony_ci return CS_SUCCESS_END; 2368e920a95Sopenharmony_ci } 2378e920a95Sopenharmony_ci 2388e920a95Sopenharmony_ci auto info = signMap_.begin(); 2398e920a95Sopenharmony_ci fileName = info->first; 2408e920a95Sopenharmony_ci signInfo = info->second; 2418e920a95Sopenharmony_ci signMap_.erase(fileName); 2428e920a95Sopenharmony_ci return CS_SUCCESS; 2438e920a95Sopenharmony_ci } 2448e920a95Sopenharmony_ci 2458e920a95Sopenharmony_ci Verify::SignatureInfo signatureInfo_; 2468e920a95Sopenharmony_ci const CodeSignBlockHeader *blockHeader_ = nullptr; 2478e920a95Sopenharmony_ci const FsVerityInfo *fsVerityInfo_ = nullptr; 2488e920a95Sopenharmony_ci const HapSignInfo *hapSignInfo_ = nullptr; 2498e920a95Sopenharmony_ci const NativeLibSignInfo *nativeLibSignInfo_ = nullptr; 2508e920a95Sopenharmony_ci std::mutex signMapMutex_; 2518e920a95Sopenharmony_ci SignMap signMap_; 2528e920a95Sopenharmony_ci}; 2538e920a95Sopenharmony_ci} // CodeSign namespace 2548e920a95Sopenharmony_ci} // Security namespace 2558e920a95Sopenharmony_ci} // OHOS namespace 2568e920a95Sopenharmony_ci#endif 257