1 /* 2 * Copyright (c) 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 #ifndef BIN_CHUNK_UPDATE 16 #define BIN_CHUNK_UPDATE 17 18 #include <cstdio> 19 #include <functional> 20 #include <string> 21 #include <sys/wait.h> 22 #include <vector> 23 #include <map> 24 #include <future> 25 26 #include "package/pkg_manager.h" 27 #include "applypatch/transfer_manager.h" 28 #include "pkg_package/pkg_pkgfile.h" 29 #include "pkg_manager/pkg_stream.h" 30 31 namespace Updater { 32 33 struct __attribute__((packed)) PkgTlvHH { 34 uint16_t type; 35 uint16_t length; 36 }; 37 38 struct __attribute__((packed)) PkgTlvHI { 39 uint16_t type; 40 uint32_t length; 41 }; 42 43 using UpdateResultCode = enum { 44 STREAM_UPDATE_SUCCESS = 0, 45 STREAM_UPDATE_FAILURE = 1, 46 STREAM_UPDATE_COMPLETE = 2 47 }; 48 49 using BinUpdateTip = enum { 50 BIN_UPDATE_ZIP_TIP = 0xaa, 51 BIN_UPDATE_HEAD_TIP = 0x01, 52 BIN_UPDATE_DATA_TIP = 0x12, 53 BIN_UPDATE_HASH_TIP = 0x16 54 }; 55 56 using ChunkInstallStep = enum { 57 CHUNK_INSTALL_STEP_PRE = 0, 58 CHUNK_INSTALL_STEP_DO, 59 CHUNK_INSTALL_STEP_POST 60 }; 61 62 struct BinChunkUpdateInfo { 63 std::vector<std::string> componentNames; 64 bool needNewData = false; 65 ChunkInstallStep updateStep = CHUNK_INSTALL_STEP_PRE; 66 int srcFd; 67 int targetFd; 68 std::unique_ptr<TransferParams> transferParams; 69 std::string curPartition; 70 std::string cmdLine; 71 int patitionNum; 72 Hpackage::DigestAlgorithm::DigestAlgorithmPtr algorithm; 73 }; 74 75 struct PartitionHashInfo { 76 std::map<std::string, std::string> hashValues; 77 std::map<std::string, uint64_t> dataLenInfos; 78 }; 79 80 class BinChunkUpdate { 81 public: 82 explicit BinChunkUpdate(uint32_t maxBufSize); 83 virtual ~BinChunkUpdate(); 84 UpdateResultCode StartBinChunkUpdate(const uint8_t *data, uint32_t len, uint32_t &dealLen); 85 private: 86 UpdateResultCode ProcessBufferData(); 87 88 UpdateResultCode ChunkInstallPreWrite(uint8_t *data, uint32_t &len); 89 UpdateResultCode ChunkInstallDoWrite(uint8_t *data, uint32_t &len); 90 UpdateResultCode ChunkInstallPostWrite(uint8_t *data, uint32_t &len); 91 92 UpdateResultCode UpdateBinHead(uint8_t *data, uint32_t &len); 93 UpdateResultCode UpdateBinData(uint8_t *data, uint32_t &len); 94 UpdateResultCode UpdateBinHash(uint8_t *data, uint32_t &len); 95 UpdateResultCode UpdateBinOther(uint8_t *data, uint32_t &len); 96 UpdateResultCode ProcessHeader(const uint8_t *data); 97 UpdateResultCode SkipTargetData(const uint8_t *data, uint32_t len, uint32_t &dealLen); 98 99 bool AddRemainData(const uint8_t *data, uint32_t &len); 100 bool MoveRemainingData(); 101 102 bool ReadPartitionData(uint8_t *data, uint32_t &len); 103 bool OpenDevPath(); 104 bool InitTransferParams(); 105 106 // 处理安装分区 107 bool ProcessPartition(uint8_t *data, uint32_t &len, uint32_t &offset); 108 // 处理安装命令 109 bool ProcessCmdLine(uint8_t *data, uint32_t &len, uint32_t &offset); 110 // 处理安装数据 111 bool ProcessInstallData(uint8_t *data, uint32_t &len, uint32_t &offset); 112 // 执行安装命令 113 bool ExecuteCmdLine(); 114 115 bool ProcessPartitionNum(uint8_t *data, uint32_t &len, uint32_t &offset); 116 117 bool ProcessPartitionData(uint8_t *data, uint32_t &len, uint32_t &offset, PartitionHashInfo &hashInfos); 118 119 bool ProcessSignature(uint8_t *data, uint32_t &len, uint32_t &offset, 120 std::vector<uint8_t> &signData); 121 122 bool ReadHash(uint8_t *data, uint32_t &len, uint32_t &offset, std::string &hashBuf); 123 124 bool ReadDataLength(uint8_t *data, uint32_t &len, uint32_t &offset, 125 const std::string &patition, std::map<std::string, uint64_t> &dataLenInfos); 126 127 bool VerifySignature(std::vector<uint8_t> &signData); 128 129 bool VerifyPartitionHashes(const PartitionHashInfo &hashInfos, std::vector<std::future<bool>> &futures); 130 131 bool VerifyPartitionHash(const std::string& partitionName, const std::string &expectedHash, 132 const std::map<std::string, uint64_t> &dataLenInfos); 133 std::string ComputeFileHash(const std::string& partitionName, const std::map<std::string, uint64_t> &dataLenInfos); 134 135 Hpackage::PkgManager::PkgManagerPtr pkgManager_; 136 uint8_t *buffer_ = nullptr; 137 uint32_t maxBufSize_ = 0; 138 uint32_t curlen_ = 0; 139 uint32_t offset_ = 0; 140 uint32_t skipLength_ = 0; 141 bool firstBuffer_ = true; 142 143 std::map<ChunkInstallStep, std::function<UpdateResultCode (uint8_t *, uint32_t &)>> chunkInstallProcess_; 144 BinChunkUpdateInfo updateInfo_ {}; 145 }; 146 } // Updater 147 #endif /* BIN_FLOW_UPDATE */ 148