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_HEAD_TIP = 0x01, 51 BIN_UPDATE_DATA_TIP = 0x12, 52 BIN_UPDATE_HASH_TIP = 0x16 53 }; 54 55 using ChunkInstallStep = enum { 56 CHUNK_INSTALL_STEP_PRE = 0, 57 CHUNK_INSTALL_STEP_DO, 58 CHUNK_INSTALL_STEP_POST 59 }; 60 61 struct BinChunkUpdateInfo { 62 std::vector<std::string> componentNames; 63 bool needNewData = false; 64 ChunkInstallStep updateStep = CHUNK_INSTALL_STEP_PRE; 65 int srcFd; 66 int targetFd; 67 std::unique_ptr<TransferParams> transferParams; 68 std::string curPartition; 69 std::string cmdLine; 70 int patitionNum; 71 Hpackage::DigestAlgorithm::DigestAlgorithmPtr algorithm; 72 }; 73 74 struct PartitionHashInfo { 75 std::map<std::string, std::string> hashValues; 76 std::map<std::string, uint64_t> dataLenInfos; 77 }; 78 79 class BinChunkUpdate { 80 public: 81 explicit BinChunkUpdate(uint32_t maxBufSize); 82 virtual ~BinChunkUpdate(); 83 UpdateResultCode StartBinChunkUpdate(const uint8_t *data, uint32_t len, uint32_t &dealLen); 84 private: 85 UpdateResultCode ProcessBufferData(); 86 87 UpdateResultCode ChunkInstallPreWrite(uint8_t *data, uint32_t &len); 88 UpdateResultCode ChunkInstallDoWrite(uint8_t *data, uint32_t &len); 89 UpdateResultCode ChunkInstallPostWrite(uint8_t *data, uint32_t &len); 90 91 UpdateResultCode UpdateBinHead(uint8_t *data, uint32_t &len); 92 UpdateResultCode UpdateBinData(uint8_t *data, uint32_t &len); 93 UpdateResultCode UpdateBinHash(uint8_t *data, uint32_t &len); 94 UpdateResultCode UpdateBinOther(uint8_t *data, uint32_t &len); 95 96 bool AddRemainData(const uint8_t *data, uint32_t &len); 97 bool MoveRemainingData(); 98 99 bool ReadPartitionData(uint8_t *data, uint32_t &len); 100 bool OpenDevPath(); 101 bool InitTransferParams(); 102 103 // 处理安装分区 104 bool ProcessPartition(uint8_t *data, uint32_t &len, uint32_t &offset); 105 // 处理安装命令 106 bool ProcessCmdLine(uint8_t *data, uint32_t &len, uint32_t &offset); 107 // 处理安装数据 108 bool ProcessInstallData(uint8_t *data, uint32_t &len, uint32_t &offset); 109 // 执行安装命令 110 bool ExecuteCmdLine(); 111 112 bool ProcessPartitionNum(uint8_t *data, uint32_t &len, uint32_t &offset); 113 114 bool ProcessPartitionData(uint8_t *data, uint32_t &len, uint32_t &offset, PartitionHashInfo &hashInfos); 115 116 bool ProcessSignature(uint8_t *data, uint32_t &len, uint32_t &offset, 117 std::vector<uint8_t> &signData); 118 119 bool ReadHash(uint8_t *data, uint32_t &len, uint32_t &offset, std::string &hashBuf); 120 121 bool ReadDataLength(uint8_t *data, uint32_t &len, uint32_t &offset, 122 const std::string &patition, std::map<std::string, uint64_t> &dataLenInfos); 123 124 bool VerifySignature(std::vector<uint8_t> &signData); 125 126 bool VerifyPartitionHashes(const PartitionHashInfo &hashInfos, std::vector<std::future<bool>> &futures); 127 128 bool VerifyPartitionHash(const std::string& partitionName, const std::string &expectedHash, 129 const std::map<std::string, uint64_t> &dataLenInfos); 130 std::string ComputeFileHash(const std::string& partitionName, const std::map<std::string, uint64_t> &dataLenInfos); 131 132 Hpackage::PkgManager::PkgManagerPtr pkgManager_; 133 uint8_t *buffer_ = nullptr; 134 uint32_t maxBufSize_ = 0; 135 uint32_t curlen_ = 0; 136 uint32_t offset_ = 0; 137 138 std::map<ChunkInstallStep, std::function<UpdateResultCode (uint8_t *, uint32_t &)>> chunkInstallProcess_; 139 BinChunkUpdateInfo updateInfo_ {}; 140 }; 141 } // Updater 142 #endif /* BIN_FLOW_UPDATE */ 143