• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "pkg_upgradefile.h"
16 #include <cerrno>
17 #include <cstdio>
18 #include <cstring>
19 #include <ctime>
20 #include <limits>
21 #include <memory>
22 #include "dump.h"
23 #include "openssl_util.h"
24 #include "pkg_verify_util.h"
25 #include "pkg_lz4file.h"
26 #include "pkg_manager.h"
27 #include "pkg_pkgfile.h"
28 #include "pkg_stream.h"
29 #include "pkg_utils.h"
30 #include "pkg_zipfile.h"
31 #include "securec.h"
32 #include "utils.h"
33 #include "updater/updater_const.h"
34 
35 #define TLV_CHECK_AND_RETURN(tlv, tlvType, len, fileLen)                                         \
36     do {                                                                                         \
37         if (!((tlv)->length < (fileLen) && (tlv)->length >= (len) && (tlv)->type == (tlvType) && \
38               ((tlv)->length + sizeof(PkgTlv)) < (fileLen))) {                                   \
39             PKG_LOGE("Invalid tlv type: %d length %u ", tlvType, ((tlv)->length));               \
40             return PKG_INVALID_FILE;                                                             \
41         }                                                                                        \
42     } while (0)
43 
44 using namespace std;
45 
46 namespace Hpackage {
47 constexpr int32_t UPGRADE_FILE_HEADER_LEN = 3 * sizeof(PkgTlv) + sizeof(UpgradePkgHeader) + sizeof(UpgradePkgTime);
48 constexpr int32_t UPGRADE_FILE_BASIC_LEN = 2 * sizeof(PkgTlv) + sizeof(UpgradePkgHeader) + sizeof(UpgradePkgTime);
49 constexpr int32_t HASH_TLV_SIZE = 6;
50 constexpr int16_t TLV_TYPE_FOR_HASH_HEADER = 0x0006;
51 constexpr int16_t TLV_TYPE_FOR_HASH_DATA = 0x0007;
52 constexpr int16_t TLV_TYPE_FOR_SIGN = 0x0008;
53 constexpr int32_t UPGRADE_RESERVE_LEN = 16;
54 constexpr int16_t TLV_TYPE_FOR_SHA256 = 0x0001;
55 constexpr int16_t TLV_TYPE_FOR_SHA384 = 0x0011;
56 constexpr size_t BUFFER_SIZE = 4 * 1024 * 1024;
57 
Init(const PkgManager::FileInfoPtr fileInfo,PkgStreamPtr inStream)58 int32_t UpgradeFileEntry::Init(const PkgManager::FileInfoPtr fileInfo, PkgStreamPtr inStream)
59 {
60     int32_t ret = PkgEntry::Init(&fileInfo_.fileInfo, fileInfo, inStream);
61     if (ret != PKG_SUCCESS) {
62         PKG_LOGE("Fail to check input param");
63         return PKG_INVALID_PARAM;
64     }
65     ComponentInfo *info = (ComponentInfo *)fileInfo;
66     if (info != nullptr) {
67         fileInfo_.version = info->version;
68         fileInfo_.id = info->id;
69         fileInfo_.resType = info->resType;
70         fileInfo_.type = info->type;
71         fileInfo_.compFlags = info->compFlags;
72         fileInfo_.originalSize = info->originalSize;
73         if (memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), info->digest, sizeof(info->digest)) != EOK) {
74             PKG_LOGE("UpgradeFileEntry memcpy failed");
75             return PKG_NONE_MEMORY;
76         }
77     }
78     return PKG_SUCCESS;
79 }
80 
GetUpgradeSignatureLen() const81 size_t UpgradePkgFile::GetUpgradeSignatureLen() const
82 {
83     return SIGN_SHA256_LEN + SIGN_SHA384_LEN;
84 }
85 
GetDigestLen() const86 size_t UpgradePkgFile::GetDigestLen() const
87 {
88     return DigestAlgorithm::GetDigestLen(pkgInfo_.pkgInfo.digestMethod);
89 }
90 
GetEntryOffset(size_t & dataOffset,const PkgManager::FileInfoPtr file)91 int32_t UpgradePkgFile::GetEntryOffset(size_t &dataOffset, const PkgManager::FileInfoPtr file)
92 {
93     if (!CheckState({PKG_FILE_STATE_IDLE, PKG_FILE_STATE_WORKING}, PKG_FILE_STATE_WORKING)) {
94         PKG_LOGE("error state curr %d ", state_);
95         return PKG_INVALID_STATE;
96     }
97     if (pkgEntryMapId_.size() >= pkgInfo_.pkgInfo.entryCount) {
98         PKG_LOGE("More entry for and for %s %zu", file->identity.c_str(), pkgEntryMapId_.size());
99         return PKG_INVALID_PARAM;
100     }
101     PKG_LOGI("Add file %s to package", file->identity.c_str());
102     size_t compDataLen = 0;
103     for (auto &it : pkgEntryMapId_) {
104         compDataLen += (*it.second).GetFileInfo()->packedSize;
105     }
106     dataOffset = UPGRADE_FILE_HEADER_LEN + pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo);
107     dataOffset += UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen();
108     dataOffset += compDataLen;
109 
110     return PKG_SUCCESS;
111 }
112 
AddEntry(const PkgManager::FileInfoPtr file,const PkgStreamPtr inStream)113 int32_t UpgradePkgFile::AddEntry(const PkgManager::FileInfoPtr file, const PkgStreamPtr inStream)
114 {
115     if (file == nullptr || inStream == nullptr) {
116         PKG_LOGE("Fail to check input param");
117         return PKG_INVALID_PARAM;
118     }
119     size_t dataOffset = 0;
120 
121     int32_t ret = GetEntryOffset(dataOffset, file);
122     if (ret != PKG_SUCCESS) {
123         PKG_LOGE("Fail to GetEntryOffset");
124         return ret;
125     }
126 
127     UpgradeFileEntry *entry = static_cast<UpgradeFileEntry *>(AddPkgEntry(file->identity));
128     if (entry == nullptr) {
129         PKG_LOGE("Fail create pkg node for %s", file->identity.c_str());
130         return PKG_NONE_MEMORY;
131     }
132     ret = entry->Init(file, inStream);
133     if (ret != PKG_SUCCESS) {
134         PKG_LOGE("Fail init entry for %s", file->identity.c_str());
135         return ret;
136     }
137 
138     size_t encodeLen = 0;
139     ret = entry->Pack(inStream, dataOffset, encodeLen);
140     if (ret != PKG_SUCCESS) {
141         PKG_LOGE("Fail Pack for %s", file->identity.c_str());
142         return ret;
143     }
144     packedFileSize_ += encodeLen;
145 
146     size_t offset = UPGRADE_FILE_HEADER_LEN + (pkgEntryMapId_.size() - 1) * sizeof(UpgradeCompInfo);
147     ret = entry->EncodeHeader(inStream, offset, encodeLen);
148     if (ret != PKG_SUCCESS) {
149         PKG_LOGE("Fail encode header for %s", file->identity.c_str());
150         return ret;
151     }
152 
153     PKG_LOGI("Header offset:%zu data offset:%zu packedFileSize: %zu", offset, dataOffset, packedFileSize_);
154     return PKG_SUCCESS;
155 }
156 
CheckPackageHeader(std::vector<uint8_t> & buffer,size_t & offset)157 int32_t UpgradePkgFile::CheckPackageHeader(std::vector<uint8_t> &buffer, size_t &offset)
158 {
159     if (!CheckState({PKG_FILE_STATE_WORKING}, PKG_FILE_STATE_CLOSE)) {
160         PKG_LOGE("error state curr %d ", state_);
161         return PKG_INVALID_STATE;
162     }
163     WriteLE16(buffer.data(), GetPackageTlvType()); // Type is 1 for package header in TLV format
164     WriteLE16(buffer.data() + sizeof(uint16_t), sizeof(UpgradePkgHeader));
165     offset += sizeof(PkgTlv);
166     UpgradePkgHeader *header = reinterpret_cast<UpgradePkgHeader *>(buffer.data() + offset);
167     if (header == nullptr) {
168         PKG_LOGE("Fail to create header");
169         return PKG_NONE_MEMORY;
170     }
171     header->pkgInfoLength = sizeof(PkgTlv) + sizeof(PkgTlv) + sizeof(PkgTlv) + sizeof(UpgradePkgHeader) +
172         sizeof(UpgradePkgTime) + pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo) + UPGRADE_RESERVE_LEN;
173     WriteLE32(reinterpret_cast<uint8_t *>(&header->updateFileVersion), pkgInfo_.updateFileVersion);
174     int32_t ret = memcpy_s(header->softwareVersion, sizeof(header->softwareVersion), pkgInfo_.softwareVersion.data(),
175         pkgInfo_.softwareVersion.size());
176     if (ret != EOK) {
177         PKG_LOGE("Fail to memcpy_s %s ret: %d", pkgStream_->GetFileName().c_str(), ret);
178         return ret;
179     }
180     ret = memcpy_s(header->productUpdateId, sizeof(header->productUpdateId), pkgInfo_.productUpdateId.data(),
181         pkgInfo_.productUpdateId.size());
182     if (ret != EOK) {
183         PKG_LOGE("Fail to memcpy_s %s ret: %d", pkgStream_->GetFileName().c_str(), ret);
184         return ret;
185     }
186     offset += sizeof(UpgradePkgHeader);
187     // 时间tlv
188     WriteLE16(buffer.data() + offset, 0x02); // Type is 2 for time in TLV format
189     WriteLE16(buffer.data() + offset + sizeof(uint16_t), sizeof(UpgradePkgTime));
190     offset += sizeof(PkgTlv);
191     return PKG_SUCCESS;
192 }
193 
WriteBuffer(std::vector<uint8_t> & buffer,size_t & offset,size_t & signOffset)194 int32_t UpgradePkgFile::WriteBuffer(std::vector<uint8_t> &buffer, size_t &offset, size_t &signOffset)
195 {
196     offset += pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo);
197     signOffset = offset + UPGRADE_RESERVE_LEN;
198 
199     buffer.assign(buffer.capacity(), 0);
200     size_t nameLen = 0;
201     int32_t ret = PkgFileImpl::ConvertStringToBuffer(
202         pkgInfo_.descriptPackageId, {buffer.data(), UPGRADE_RESERVE_LEN}, nameLen);
203     if (ret != PKG_SUCCESS) {
204         PKG_LOGE("Fail write descriptPackageId");
205         return ret;
206     }
207     ret = pkgStream_->Write(buffer, GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN, offset);
208     if (ret != PKG_SUCCESS) {
209         PKG_LOGE("Fail write sign for %s", pkgStream_->GetFileName().c_str());
210         return ret;
211     }
212     PKG_LOGI("SavePackage success file length: %zu signOffset %zu", pkgStream_->GetFileLength(), signOffset);
213     pkgStream_->Flush(offset);
214     return PKG_SUCCESS;
215 }
216 
SavePackage(size_t & signOffset)217 int32_t UpgradePkgFile::SavePackage(size_t &signOffset)
218 {
219     PKG_LOGI("SavePackage %s", pkgStream_->GetFileName().c_str());
220 
221     // Allocate buffer size with max possible size
222     size_t buffSize = GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN;
223     buffSize = ((UPGRADE_FILE_HEADER_LEN > buffSize) ? UPGRADE_FILE_HEADER_LEN : buffSize);
224     std::vector<uint8_t> buffer(buffSize);
225 
226     size_t offset = 0;
227     // Package header information
228     int32_t ret = CheckPackageHeader(buffer, offset);
229     if (ret != PKG_SUCCESS) {
230         PKG_LOGE("Fail to CheckPackageHeader");
231         return PKG_NONE_MEMORY;
232     }
233 
234     UpgradePkgTime *time = reinterpret_cast<UpgradePkgTime *>(buffer.data() + offset);
235     ret = memcpy_s(time->date, sizeof(time->date), pkgInfo_.date.data(), pkgInfo_.date.size());
236     if (ret != EOK) {
237         PKG_LOGE("Fail to memcpy_s %s ret: %d", pkgStream_->GetFileName().c_str(), ret);
238         return PKG_NONE_MEMORY;
239     }
240     ret = memcpy_s(time->time, sizeof(time->time), pkgInfo_.time.data(), pkgInfo_.time.size());
241     if (ret != EOK) {
242         PKG_LOGE("Fail to memcpy_s %s ret: %d", pkgStream_->GetFileName().c_str(), ret);
243         return PKG_NONE_MEMORY;
244     }
245     offset += sizeof(UpgradePkgTime);
246     // 组件的tlv
247     WriteLE16(buffer.data() + offset, 0x05); // Type is 5 for component in TLV format
248     WriteLE16(buffer.data() + offset + sizeof(uint16_t), pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo));
249     offset += sizeof(PkgTlv);
250     ret = pkgStream_->Write(buffer, UPGRADE_FILE_HEADER_LEN, 0);
251     if (ret != PKG_SUCCESS) {
252         PKG_LOGE("Fail write upgrade file header for %s ret: %d", pkgStream_->GetFileName().c_str(), ret);
253         return ret;
254     }
255     // Clear buffer and save signature information
256     ret = WriteBuffer(buffer, offset, signOffset);
257     if (ret != PKG_SUCCESS) {
258         PKG_LOGE("Fail WriteBuffer");
259         return ret;
260     }
261     return PKG_SUCCESS;
262 }
263 
ReadSignData(std::vector<uint8_t> & signData,size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm)264 int32_t UpgradePkgFile::ReadSignData(std::vector<uint8_t> &signData,
265     size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm)
266 {
267     Updater::UPDATER_INIT_RECORD;
268     size_t readBytes = 0;
269     size_t signLen = parsedLen;
270     PkgBuffer buffer(HASH_TLV_SIZE);
271     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, readBytes);
272     if (ret != PKG_SUCCESS) {
273         PKG_LOGE("read sign data fail");
274         UPDATER_LAST_WORD(ret, parsedLen);
275         return ret;
276     }
277     parsedLen += buffer.length;
278     uint16_t dataType = ReadLE16(buffer.buffer);
279     uint32_t dataLen = ReadLE32(buffer.buffer + sizeof(uint16_t));
280     if (dataType != TLV_TYPE_FOR_SIGN) {
281         PKG_LOGE("Invalid tlv type: %hu length %u ", dataType, dataLen);
282         UPDATER_LAST_WORD(ret, dataType);
283         return PKG_INVALID_FILE;
284     }
285 
286     PkgBuffer signBuf(dataLen);
287     ret = pkgStream_->Read(signBuf, parsedLen, signBuf.length, readBytes);
288     if (ret != PKG_SUCCESS) {
289         PKG_LOGE("read hash data fail");
290         UPDATER_LAST_WORD(ret, parsedLen);
291         return ret;
292     }
293     parsedLen += signBuf.length;
294     signData.resize(dataLen);
295     signData.assign(signBuf.data.begin(), signBuf.data.end());
296 
297     // refresh component data offset
298     signLen = parsedLen - signLen;
299     for (auto &it : pkgEntryMapId_) {
300         if (it.second != nullptr) {
301             it.second->AddDataOffset(signLen);
302         }
303     }
304     return PKG_SUCCESS;
305 }
306 
ReadImgHashTLV(std::vector<uint8_t> & imgHashBuf,size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,uint32_t needType)307 int32_t UpgradePkgFile::ReadImgHashTLV(std::vector<uint8_t> &imgHashBuf, size_t &parsedLen,
308                                        DigestAlgorithm::DigestAlgorithmPtr algorithm, uint32_t needType)
309 {
310     Updater::UPDATER_INIT_RECORD;
311     size_t readBytes = 0;
312     PkgBuffer buffer(HASH_TLV_SIZE);
313     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, readBytes);
314     if (ret != PKG_SUCCESS) {
315         PKG_LOGE("read image hash header fail");
316         UPDATER_LAST_WORD(ret, "read image hash header fail");
317         return ret;
318     }
319 
320     parsedLen += buffer.length;
321     uint16_t type = ReadLE16(buffer.buffer);
322     uint32_t len = ReadLE32(buffer.buffer + sizeof(uint16_t));
323     if (type != needType) {
324         PKG_LOGE("Invalid tlv type: %d length %u ", type, len);
325         return PKG_INVALID_FILE;
326     }
327     algorithm->Update(buffer, buffer.length);
328     imgHashBuf.insert(imgHashBuf.end(), buffer.data.begin(), buffer.data.end());
329 
330     PkgBuffer dataBuf(len);
331     ret = pkgStream_->Read(dataBuf, parsedLen, dataBuf.length, readBytes);
332     if (ret != PKG_SUCCESS) {
333         PKG_LOGE("read hash data fail");
334         UPDATER_LAST_WORD(ret, "read hash data fail");
335         return ret;
336     }
337     parsedLen += dataBuf.length;
338     algorithm->Update(dataBuf, dataBuf.length);
339     imgHashBuf.insert(imgHashBuf.end(), dataBuf.data.begin(), dataBuf.data.end());
340     return PKG_SUCCESS;
341 }
342 
ReadImgHashData(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm)343 int32_t UpgradePkgFile::ReadImgHashData(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm)
344 {
345     Updater::UPDATER_INIT_RECORD;
346 #ifndef DIFF_PATCH_SDK
347     if ((!Updater::Utils::CheckUpdateMode(Updater::SDCARD_MODE) &&
348         !Updater::Utils::CheckUpdateMode(Updater::USB_MODE) &&
349         !Updater::Utils::CheckUpdateMode(Updater::SDCARD_INTRAL_MODE)) ||
350         pkgInfo_.updateFileVersion < UPGRADE_FILE_VERSION_V2) {
351         PKG_LOGI("ignore image hash check");
352         return PKG_SUCCESS;
353     }
354 #endif
355 
356     std::vector<uint8_t> imgHashBuf;
357     // read hash header
358     int32_t ret = ReadImgHashTLV(imgHashBuf, parsedLen, algorithm, TLV_TYPE_FOR_HASH_HEADER);
359     if (ret != PKG_SUCCESS) {
360         PKG_LOGE("read image hash info fail");
361         UPDATER_LAST_WORD(ret, "read image hash info fail");
362         return ret;
363     }
364 
365     // read hash data
366     ret = ReadImgHashTLV(imgHashBuf, parsedLen, algorithm, TLV_TYPE_FOR_HASH_DATA);
367     if (ret != PKG_SUCCESS) {
368         PKG_LOGE("read image hash data fail");
369         UPDATER_LAST_WORD(ret, "read image hash data fail");
370         return ret;
371     }
372 
373     // refresh component data offset
374     for (auto &it : pkgEntryMapId_) {
375         it.second->AddDataOffset(imgHashBuf.size());
376     }
377 
378 #ifndef DIFF_PATCH_SDK
379     if (pkgInfo_.updateFileVersion >= UPGRADE_FILE_VERSION_V3) {
380         hashCheck_ = LoadImgHashDataNew(imgHashBuf.data(), imgHashBuf.size());
381     } else {
382         hashCheck_ = LoadImgHashData(imgHashBuf.data(), imgHashBuf.size());
383     }
384     if (hashCheck_ == nullptr) {
385         PKG_LOGE("pause hash data fail");
386         return PKG_INVALID_FILE;
387     }
388 #endif
389 
390     return PKG_SUCCESS;
391 }
392 
ReadPackageInfo(std::vector<uint8_t> & signData,size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm)393 int32_t UpgradePkgFile::ReadPackageInfo(std::vector<uint8_t> &signData, size_t &parsedLen,
394     DigestAlgorithm::DigestAlgorithmPtr algorithm)
395 {
396     Updater::UPDATER_INIT_RECORD;
397     PkgBuffer buffer(GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN);
398     size_t readBytes = 0;
399     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, readBytes);
400     if (ret != PKG_SUCCESS) {
401         PKG_LOGE("read sign data fail");
402         UPDATER_LAST_WORD(ret, "read sign data fail");
403         return ret;
404     }
405 
406     PkgFileImpl::ConvertBufferToString(pkgInfo_.descriptPackageId, {buffer.buffer, UPGRADE_RESERVE_LEN});
407     if (pkgInfo_.pkgInfo.digestMethod == PKG_DIGEST_TYPE_SHA384) {
408         signData.resize(SIGN_SHA384_LEN);
409         ret = memcpy_s(signData.data(), signData.size(),
410             buffer.buffer + UPGRADE_RESERVE_LEN + SIGN_SHA256_LEN, SIGN_SHA384_LEN);
411     } else {
412         signData.resize(SIGN_SHA256_LEN);
413         ret = memcpy_s(signData.data(), signData.size(), buffer.buffer + UPGRADE_RESERVE_LEN, SIGN_SHA256_LEN);
414     }
415     if (ret != EOK) {
416         PKG_LOGE("memcpy sign data fail");
417         UPDATER_LAST_WORD(PKG_NONE_MEMORY, "memcpy sign data fail");
418         return PKG_NONE_MEMORY;
419     }
420 
421     // refresh component data offset
422     for (auto &it : pkgEntryMapId_) {
423         if (it.second != nullptr) {
424             it.second->AddDataOffset(GetUpgradeSignatureLen());
425         }
426     }
427 
428     ret = memset_s(buffer.buffer + UPGRADE_RESERVE_LEN, buffer.length, 0, GetUpgradeSignatureLen());
429     if (ret != EOK) {
430         PKG_LOGE("memset buff fail");
431         UPDATER_LAST_WORD(PKG_NONE_MEMORY, "memset buff fail");
432         return PKG_NONE_MEMORY;
433     }
434     algorithm->Update(buffer, UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen());
435     parsedLen += UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen();
436     return PKG_SUCCESS;
437 }
438 
LoadPackage(std::vector<std::string> & fileNames,VerifyFunction verifier)439 int32_t UpgradePkgFile::LoadPackage(std::vector<std::string> &fileNames, VerifyFunction verifier)
440 {
441     Updater::UPDATER_INIT_RECORD;
442     if (verifier == nullptr) {
443         PKG_LOGE("Check verifier nullptr");
444         UPDATER_LAST_WORD(PKG_INVALID_SIGNATURE, "Check verifier nullptr");
445         return PKG_INVALID_SIGNATURE;
446     }
447     if (!CheckState({PKG_FILE_STATE_IDLE}, PKG_FILE_STATE_WORKING)) {
448         PKG_LOGE("error state curr %d ", state_);
449         UPDATER_LAST_WORD(PKG_INVALID_STATE, "error state curr");
450         return PKG_INVALID_STATE;
451     }
452     PKG_LOGI("LoadPackage %s ", pkgStream_->GetFileName().c_str());
453     size_t fileLen = pkgStream_->GetFileLength();
454     // Allocate buffer with smallest package size
455     size_t buffSize = UPGRADE_FILE_HEADER_LEN + sizeof(UpgradeCompInfo) +
456         GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN;
457     if (fileLen < buffSize) {
458         PKG_LOGE("Invalid file %s fileLen:%zu ", pkgStream_->GetFileName().c_str(), fileLen);
459         UPDATER_LAST_WORD(PKG_INVALID_STATE, "Invalid file " + pkgStream_->GetFileName(), fileLen);
460         return PKG_INVALID_FILE;
461     }
462 
463     DigestAlgorithm::DigestAlgorithmPtr algorithm = nullptr;
464     // Parse header
465     size_t parsedLen = 0;
466     int32_t ret = ReadUpgradePkgHeader(parsedLen, algorithm);
467     if (ret != PKG_SUCCESS) {
468         PKG_LOGE("Decode header fail %d", ret);
469         UPDATER_LAST_WORD(ret, "Decode header fail");
470         return ret;
471     }
472 
473     ret = ReadComponents(parsedLen, algorithm, fileNames);
474     if (ret != PKG_SUCCESS) {
475         PKG_LOGE("Decode components fail %d", ret);
476         UPDATER_LAST_WORD(ret, "Decode components fail");
477         return ret;
478     }
479 
480     ret = VerifyFile(parsedLen, algorithm, verifier);
481     pkgInfo_.pkgInfo.updateFileHeadLen = parsedLen;
482     return ret;
483 }
484 
VerifyFile(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier)485 int32_t UpgradePkgFile::VerifyFile(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm,
486                                    VerifyFunction verifier)
487 {
488     if (pkgInfo_.updateFileVersion >= UPGRADE_FILE_VERSION_V2) {
489         return VerifyFileV2(parsedLen, algorithm, verifier);
490     }
491 
492     return VerifyFileV1(parsedLen, algorithm, verifier);
493 }
494 
VerifyFileV1(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier)495 int32_t UpgradePkgFile::VerifyFileV1(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm,
496                                      VerifyFunction verifier)
497 {
498     std::vector<uint8_t> signData;
499     // Read signature information
500     int32_t ret = ReadPackageInfo(signData, parsedLen, algorithm);
501     if (ret != PKG_SUCCESS) {
502         PKG_LOGE("ReadPackageInfo fail %d", ret);
503         return ret;
504     }
505     // Calculate digest and verify
506     return Verify(parsedLen, algorithm, verifier, signData);
507 }
508 
VerifyFileV2(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier)509 int32_t UpgradePkgFile::VerifyFileV2(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm,
510                                      VerifyFunction verifier)
511 {
512     int32_t ret = ReadReserveData(parsedLen, algorithm);
513     if (ret != PKG_SUCCESS) {
514         PKG_LOGE("ReadReserveData fail %d", ret);
515         return ret;
516     }
517 
518     // Read image hash information
519     ret = ReadImgHashData(parsedLen, algorithm);
520     if (ret != PKG_SUCCESS) {
521         PKG_LOGW("LoadImgHashData fail %d, ignore image hash check", ret);
522         return ret;
523     }
524 
525     // Read signature information
526     std::vector<uint8_t> signData;
527     ret = ReadSignData(signData, parsedLen, algorithm);
528     if (ret != PKG_SUCCESS) {
529         PKG_LOGE("ReadSignData fail %d", ret);
530         return ret;
531     }
532     return VerifyHeader(algorithm, verifier, signData);
533 }
534 
Verify(size_t start,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier,const std::vector<uint8_t> & signData)535 int32_t UpgradePkgFile::Verify(size_t start, DigestAlgorithm::DigestAlgorithmPtr algorithm,
536     VerifyFunction verifier, const std::vector<uint8_t> &signData)
537 {
538     Updater::UPDATER_INIT_RECORD;
539     int ret = 0;
540     size_t buffSize = BUFFER_SIZE;
541     size_t offset = start;
542     size_t readBytes = 0;
543     PkgBuffer buffer(buffSize);
544 
545     while (offset + readBytes < pkgStream_->GetFileLength()) {
546         offset += readBytes;
547         readBytes = 0;
548         size_t remainBytes = pkgStream_->GetFileLength() - offset;
549         remainBytes = ((remainBytes > buffSize) ? buffSize : remainBytes);
550         ret = pkgStream_->Read(buffer, offset, remainBytes, readBytes);
551         if (ret != PKG_SUCCESS) {
552             PKG_LOGE("Fail to read data ");
553             UPDATER_LAST_WORD(ret, "Fail to read data ");
554             return ret;
555         }
556         algorithm->Update(buffer, readBytes);
557         pkgManager_->PostDecodeProgress(POST_TYPE_VERIFY_PKG, remainBytes, nullptr);
558     }
559 
560     PkgBuffer digest(GetDigestLen());
561     algorithm->Final(digest);
562     ret = verifier(&pkgInfo_.pkgInfo, digest.data, signData);
563     if (ret != 0) {
564         PKG_LOGE("Fail to verifier signature");
565         UPDATER_LAST_WORD(PKG_INVALID_SIGNATURE, "Fail to verifier signature");
566         return PKG_INVALID_SIGNATURE;
567     }
568     return 0;
569 }
570 
VerifyHeader(DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier,const std::vector<uint8_t> & signData)571 int32_t UpgradePkgFile::VerifyHeader(DigestAlgorithm::DigestAlgorithmPtr algorithm,
572     VerifyFunction verifier, const std::vector<uint8_t> &signData)
573 {
574     Updater::UPDATER_INIT_RECORD;
575     PkgBuffer digest(GetDigestLen());
576     algorithm->Final(digest);
577     int ret = 0;
578     if (pkgInfo_.updateFileVersion >= UPGRADE_FILE_VERSION_V4) {
579         auto signature = signData;
580         PkgVerifyUtil pkgVerifyUtil;
581         ret = pkgVerifyUtil.VerifySign(signature, digest.data);
582     } else {
583         ret = verifier(&pkgInfo_.pkgInfo, digest.data, signData);
584     }
585     if (ret != 0) {
586         PKG_LOGE("Fail to verifier signature");
587         UPDATER_LAST_WORD(PKG_INVALID_SIGNATURE);
588         return PKG_INVALID_SIGNATURE;
589     }
590     return 0;
591 }
592 
SaveEntry(const PkgBuffer & buffer,size_t & parsedLen,UpgradeParam & info,DigestAlgorithm::DigestAlgorithmPtr algorithm,std::vector<std::string> & fileNames)593 int32_t UpgradePkgFile::SaveEntry(const PkgBuffer &buffer, size_t &parsedLen, UpgradeParam &info,
594     DigestAlgorithm::DigestAlgorithmPtr algorithm, std::vector<std::string> &fileNames)
595 {
596     UpgradeFileEntry *entry = new (std::nothrow) UpgradeFileEntry(this, nodeId_++);
597     if (entry == nullptr) {
598         PKG_LOGE("Fail create upgrade node for %s", pkgStream_->GetFileName().c_str());
599         return PKG_NONE_MEMORY;
600     }
601 
602     // Extract header information from file
603     size_t decodeLen = 0;
604     PkgBuffer headerBuff(buffer.buffer + info.currLen, info.readLen - info.currLen);
605     int32_t ret = entry->DecodeHeader(headerBuff, parsedLen + info.srcOffset, info.dataOffset, decodeLen);
606     if (ret != PKG_SUCCESS) {
607         delete entry;
608         PKG_LOGE("Fail to decode header");
609         return ret;
610     }
611     // Save entry
612     pkgEntryMapId_.insert(pair<uint32_t, PkgEntryPtr>(entry->GetNodeId(), entry));
613     pkgEntryMapFileName_.insert(std::pair<std::string, PkgEntryPtr>(entry->GetFileName(), entry));
614     fileNames.push_back(entry->GetFileName());
615 
616     PkgBuffer signBuffer(buffer.buffer + info.currLen, decodeLen);
617     algorithm->Update(signBuffer, decodeLen); // Generate digest for components
618 
619     info.currLen += decodeLen;
620     info.srcOffset += decodeLen;
621 
622     if (entry->GetFileInfo() == nullptr) {
623         delete entry;
624         PKG_LOGE("Failed to get file info");
625         return PKG_INVALID_FILE;
626     }
627 
628     info.dataOffset += entry->GetFileInfo()->packedSize;
629     pkgInfo_.pkgInfo.entryCount++;
630     PKG_LOGI("Component packedSize %zu unpackedSize %zu %s", entry->GetFileInfo()->packedSize,
631         entry->GetFileInfo()->unpackedSize, entry->GetFileInfo()->identity.c_str());
632     return PKG_SUCCESS;
633 }
634 
ReadComponents(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,std::vector<std::string> & fileNames)635 int32_t UpgradePkgFile::ReadComponents(size_t &parsedLen,
636     DigestAlgorithm::DigestAlgorithmPtr algorithm, std::vector<std::string> &fileNames)
637 {
638     Updater::UPDATER_INIT_RECORD;
639     UpgradeParam info;
640     size_t fileLen = pkgStream_->GetFileLength();
641     info.readLen = 0;
642     PkgBuffer buffer(sizeof(PkgTlv));
643     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, info.readLen);
644     if (ret != PKG_SUCCESS) {
645         PKG_LOGE("Read component fail");
646         UPDATER_LAST_WORD(ret, "Read component fail");
647         return ret;
648     }
649     PkgTlv tlv;
650     tlv.type = ReadLE16(buffer.buffer);
651     tlv.length = ReadLE16(buffer.buffer + sizeof(uint16_t));
652     TLV_CHECK_AND_RETURN(&tlv, 5, sizeof(UpgradeCompInfo), fileLen); // component type is 5
653     algorithm->Update(buffer, sizeof(PkgTlv)); // tlv generate digest
654 
655     parsedLen += sizeof(PkgTlv);
656 
657     info.dataOffset = parsedLen + tlv.length + UPGRADE_RESERVE_LEN;
658     info.srcOffset = 0;
659     info.currLen = sizeof(PkgTlv);
660     PkgBuffer compBuffer(sizeof(UpgradeCompInfo));
661     while (info.srcOffset < tlv.length) {
662         if (info.currLen + sizeof(UpgradeCompInfo) > info.readLen) {
663             info.readLen = 0;
664             ret = pkgStream_->Read(compBuffer, parsedLen + info.srcOffset, compBuffer.length, info.readLen);
665             if (ret != PKG_SUCCESS) {
666                 PKG_LOGE("Fail to read data");
667                 UPDATER_LAST_WORD(ret, "Fail to read data");
668                 return ret;
669             }
670             info.currLen = 0;
671         }
672         ret = SaveEntry(compBuffer, parsedLen, info, algorithm, fileNames);
673         if (ret != PKG_SUCCESS) {
674             PKG_LOGE("SaveEntry");
675             UPDATER_LAST_WORD(ret, "SaveEntry");
676             return ret;
677         }
678     }
679     parsedLen += info.srcOffset;
680     return PKG_SUCCESS;
681 }
682 
ParsePkgHeaderToTlv(const PkgBuffer & buffer,size_t & currLen,PkgTlv & tlv)683 void UpgradePkgFile::ParsePkgHeaderToTlv(const PkgBuffer &buffer, size_t &currLen, PkgTlv &tlv)
684 {
685     pkgInfo_.pkgInfo.pkgType = PkgFile::PKG_TYPE_UPGRADE;
686     pkgInfo_.pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
687     pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256;
688 
689     tlv.type = ReadLE16(buffer.buffer);
690     tlv.length = ReadLE16(buffer.buffer + sizeof(uint16_t));
691     if (tlv.type == TLV_TYPE_FOR_SHA384) {
692         pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA384;
693     }
694 
695     // Header information
696     currLen = sizeof(PkgTlv);
697     UpgradePkgHeader *header = reinterpret_cast<UpgradePkgHeader *>(buffer.buffer + currLen);
698     pkgInfo_.updateFileVersion = ReadLE32(buffer.buffer + currLen + offsetof(UpgradePkgHeader, updateFileVersion));
699     PkgFileImpl::ConvertBufferToString(pkgInfo_.softwareVersion, {header->softwareVersion,
700         sizeof(header->softwareVersion)});
701     PkgFileImpl::ConvertBufferToString(pkgInfo_.productUpdateId, {header->productUpdateId,
702         sizeof(header->productUpdateId)});
703 }
704 
ReadReserveData(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr & algorithm)705 int32_t UpgradePkgFile::ReadReserveData(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr &algorithm)
706 {
707     Updater::UPDATER_INIT_RECORD;
708     size_t readBytes = 0;
709     PkgBuffer reserve_buf(UPGRADE_RESERVE_LEN);
710     int32_t ret = pkgStream_->Read(reserve_buf, parsedLen, reserve_buf.length, readBytes);
711     if (ret != PKG_SUCCESS) {
712         PKG_LOGE("read reserve data fail");
713         UPDATER_LAST_WORD(ret);
714         return ret;
715     }
716     PkgFileImpl::ConvertBufferToString(pkgInfo_.descriptPackageId, {reserve_buf.buffer, UPGRADE_RESERVE_LEN});
717     algorithm->Update(reserve_buf, reserve_buf.length);
718     parsedLen += reserve_buf.length;
719     return PKG_SUCCESS;
720 }
721 
ReadUpgradePkgHeader(size_t & realLen,DigestAlgorithm::DigestAlgorithmPtr & algorithm)722 int32_t UpgradePkgFile::ReadUpgradePkgHeader(size_t &realLen, DigestAlgorithm::DigestAlgorithmPtr &algorithm)
723 {
724     Updater::UPDATER_INIT_RECORD;
725     size_t fileLen = pkgStream_->GetFileLength();
726     size_t readLen = 0;
727     size_t currLen = 0;
728     PkgTlv tlv;
729     PkgBuffer buffer(UPGRADE_FILE_BASIC_LEN);
730     int32_t ret = pkgStream_->Read(buffer, 0, buffer.length, readLen);
731     if (ret != PKG_SUCCESS) {
732         PKG_LOGE("Fail to read header");
733         UPDATER_LAST_WORD(ret, "Fail to read header");
734         return ret;
735     }
736 
737     ParsePkgHeaderToTlv(buffer, currLen, tlv);
738     algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(pkgInfo_.pkgInfo.digestMethod);
739     if (algorithm == nullptr) {
740         PKG_LOGE("Invalid file %s", pkgStream_->GetFileName().c_str());
741         UPDATER_LAST_WORD(PKG_NOT_EXIST_ALGORITHM, "invalid file " + pkgStream_->GetFileName());
742         return PKG_NOT_EXIST_ALGORITHM;
743     }
744     algorithm->Init();
745 
746     if (currLen + tlv.length >= readLen) { // Extra TLV information, read it.
747         realLen = currLen + tlv.length;
748         algorithm->Update(buffer, realLen);
749         ret = pkgStream_->Read(buffer, realLen, buffer.length, readLen);
750         if (ret != PKG_SUCCESS) {
751             PKG_LOGE("Fail to read header");
752             UPDATER_LAST_WORD(ret, "Fail to read TLV");
753             return ret;
754         }
755         currLen = 0;
756     } else {
757         currLen += tlv.length;
758     }
759     // Time information
760     tlv.type = ReadLE16(buffer.buffer + currLen);
761     tlv.length = ReadLE16(buffer.buffer + currLen + sizeof(uint16_t));
762     TLV_CHECK_AND_RETURN(&tlv, sizeof(uint16_t), sizeof(UpgradePkgTime), fileLen);
763     currLen += sizeof(PkgTlv);
764     UpgradePkgTime *time = reinterpret_cast<UpgradePkgTime *>(buffer.buffer + currLen);
765     PkgFileImpl::ConvertBufferToString(pkgInfo_.date, {time->date, sizeof(time->date)});
766     PkgFileImpl::ConvertBufferToString(pkgInfo_.time, {time->time, sizeof(time->time)});
767     currLen += tlv.length;
768     realLen += currLen;
769 
770     // Parser header to get compressional algorithm
771     algorithm->Update(buffer, currLen); // Generate digest
772     return PKG_SUCCESS;
773 }
774 
GetUpGradeCompInfo(UpgradeCompInfo & comp)775 int32_t UpgradeFileEntry::GetUpGradeCompInfo(UpgradeCompInfo &comp)
776 {
777     if (memset_s(&comp, sizeof(comp), 0, sizeof(comp)) != EOK) {
778         PKG_LOGE("UpgradeFileEntry memset_s failed");
779         return PKG_NONE_MEMORY;
780     }
781     size_t len = 0;
782     int32_t ret = PkgFileImpl::ConvertStringToBuffer(
783         fileInfo_.fileInfo.identity, {comp.address, sizeof(comp.address)}, len);
784     if (ret != PKG_SUCCESS) {
785         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
786         return PKG_INVALID_PARAM;
787     }
788 
789     ret = PkgFileImpl::ConvertStringToBuffer(fileInfo_.version, {comp.version, sizeof(comp.version)}, len);
790     if (ret != PKG_SUCCESS) {
791         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
792         return PKG_INVALID_PARAM;
793     }
794     ret = memcpy_s(comp.digest, sizeof(comp.digest), fileInfo_.digest, sizeof(fileInfo_.digest));
795     if (ret != EOK) {
796         PKG_LOGE("Fail to memcpy_s ret: %d", ret);
797         return ret;
798     }
799     return PKG_SUCCESS;
800 }
801 
EncodeHeader(PkgStreamPtr inStream,size_t startOffset,size_t & encodeLen)802 int32_t UpgradeFileEntry::EncodeHeader(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen)
803 {
804     PkgStreamPtr outStream = pkgFile_->GetPkgStream();
805     if (outStream == nullptr || inStream == nullptr) {
806         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
807         return PKG_INVALID_PARAM;
808     }
809 
810     UpgradeCompInfo comp;
811     int ret = GetUpGradeCompInfo(comp);
812     if (ret != PKG_SUCCESS) {
813         PKG_LOGE("GetUpGradeCompInfo failed");
814         return ret;
815     }
816 
817     WriteLE32(reinterpret_cast<uint8_t *>(&comp.size), fileInfo_.fileInfo.unpackedSize);
818     WriteLE16(reinterpret_cast<uint8_t *>(&comp.id), fileInfo_.id);
819     WriteLE32(reinterpret_cast<uint8_t *>(&comp.originalSize), fileInfo_.originalSize);
820     comp.resType = fileInfo_.resType;
821     comp.flags = fileInfo_.compFlags;
822     comp.type = fileInfo_.type;
823 
824     headerOffset_ = startOffset;
825     PkgBuffer buffer(reinterpret_cast<uint8_t *>(&comp), sizeof(comp));
826     ret = outStream->Write(buffer, sizeof(comp), startOffset);
827     if (ret != PKG_SUCCESS) {
828         PKG_LOGE("Fail write header for %s", fileName_.c_str());
829         return ret;
830     }
831     encodeLen = sizeof(UpgradeCompInfo);
832 
833     PKG_LOGI("EncodeHeader startOffset: %zu %zu packedSize:%zu %zu ", headerOffset_, dataOffset_,
834         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize);
835     return PKG_SUCCESS;
836 }
837 
Pack(PkgStreamPtr inStream,size_t startOffset,size_t & encodeLen)838 int32_t UpgradeFileEntry::Pack(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen)
839 {
840     PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo);
841     PkgStreamPtr outStream = pkgFile_->GetPkgStream();
842     if (algorithm == nullptr || outStream == nullptr || inStream == nullptr) {
843         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
844         return PKG_INVALID_PARAM;
845     }
846 
847     PkgAlgorithmContext context = {
848         {0, startOffset},
849         {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize},
850         0, fileInfo_.fileInfo.digestMethod
851     };
852     if (memcpy_s(context.digest, sizeof(context.digest), fileInfo_.digest, sizeof(fileInfo_.digest)) != EOK) {
853         PKG_LOGE("UpgradeFileEntry pack memcpy failed");
854         return PKG_NONE_MEMORY;
855     }
856     int32_t ret = algorithm->Pack(inStream, outStream, context);
857     if (ret != PKG_SUCCESS) {
858         PKG_LOGE("Fail Compress for %s", fileName_.c_str());
859         return ret;
860     }
861 
862     // Fill digest and compressed size of file
863     if (memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), context.digest, sizeof(context.digest)) != EOK) {
864         PKG_LOGE("UpgradeFileEntry pack memcpy failed");
865         return PKG_NONE_MEMORY;
866     }
867     fileInfo_.fileInfo.packedSize = context.packedSize;
868     dataOffset_ = startOffset;
869     encodeLen = fileInfo_.fileInfo.packedSize;
870     PKG_LOGI("Pack start:%zu unpackSize:%zu packSize:%zu", startOffset, fileInfo_.fileInfo.unpackedSize,
871         fileInfo_.fileInfo.packedSize);
872     return PKG_SUCCESS;
873 }
874 
DecodeHeader(PkgBuffer & buffer,size_t headerOffset,size_t dataOffset,size_t & decodeLen)875 int32_t UpgradeFileEntry::DecodeHeader(PkgBuffer &buffer, size_t headerOffset, size_t dataOffset,
876     size_t &decodeLen)
877 {
878     UpgradePkgFile *pkgFile = static_cast<UpgradePkgFile*>(GetPkgFile());
879     if (pkgFile == nullptr) {
880         PKG_LOGE("Get pkg file ptr fail");
881         return PKG_INVALID_PARAM;
882     }
883 
884     PkgStreamPtr inStream = pkgFile->GetPkgStream();
885     if (inStream == nullptr) {
886         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
887         return PKG_INVALID_PARAM;
888     }
889     if (buffer.length < sizeof(UpgradeCompInfo)) {
890         PKG_LOGE("Fail to check buffer %zu", buffer.length);
891         return PKG_INVALID_PKG_FORMAT;
892     }
893 
894     UpgradeCompInfo *info = reinterpret_cast<UpgradeCompInfo *>(buffer.buffer);
895     if (pkgFile->GetUpgradeFileVer() >= UPGRADE_FILE_VERSION_V3) {
896         fileInfo_.fileInfo.packedSize = ReadLE64(buffer.buffer + offsetof(UpgradeCompInfo, size));
897     } else {
898         fileInfo_.fileInfo.packedSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, size));
899         fileInfo_.originalSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, originalSize));
900     }
901     fileInfo_.fileInfo.unpackedSize = fileInfo_.fileInfo.packedSize;
902     fileInfo_.fileInfo.packMethod = PKG_COMPRESS_METHOD_NONE;
903     fileInfo_.fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE;
904     fileInfo_.fileInfo.resType = info->resType;
905     int32_t ret = memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), info->digest, sizeof(info->digest));
906     if (ret != EOK) {
907         PKG_LOGE("Fail to memcpy_s ret: %d", ret);
908         return ret;
909     }
910     PkgFileImpl::ConvertBufferToString(fileInfo_.fileInfo.identity, {info->address, sizeof(info->address)});
911     PkgFileImpl::ConvertBufferToString(fileInfo_.version, {info->version, sizeof(info->version)});
912     fileName_ = fileInfo_.fileInfo.identity;
913     fileInfo_.id = ReadLE16(buffer.buffer + offsetof(UpgradeCompInfo, id));
914     fileInfo_.resType = info->resType;
915     fileInfo_.compFlags = info->flags;
916     fileInfo_.type = info->type;
917 
918     headerOffset_ = headerOffset;
919     dataOffset_ = dataOffset;
920     decodeLen = sizeof(UpgradeCompInfo);
921 
922     PKG_LOGI("Component offset: %zu %zu packedSize:%zu %zu %s", headerOffset, dataOffset,
923         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize, fileName_.c_str());
924     return PKG_SUCCESS;
925 }
926 
Unpack(PkgStreamPtr outStream)927 int32_t UpgradeFileEntry::Unpack(PkgStreamPtr outStream)
928 {
929     PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo);
930     if (algorithm == nullptr) {
931         PKG_LOGE("can not algorithm for %s", fileName_.c_str());
932         return PKG_INVALID_PARAM;
933     }
934 
935     PkgStreamPtr inStream = pkgFile_->GetPkgStream();
936     if (outStream == nullptr || inStream == nullptr) {
937         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
938         return PKG_INVALID_PARAM;
939     }
940     PkgAlgorithmContext context = {
941         {this->dataOffset_, 0},
942         {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize},
943         0, fileInfo_.fileInfo.digestMethod
944     };
945     int32_t ret = memcpy_s(context.digest, sizeof(context.digest), fileInfo_.digest, sizeof(fileInfo_.digest));
946     if (ret != EOK) {
947         PKG_LOGE("Fail to memcpy_s ret: %d", ret);
948         return ret;
949     }
950     ret = algorithm->UnpackWithVerify(inStream, outStream, context,
951         [this](PkgBuffer &buffer, size_t len, size_t offset) ->int32_t {
952             return Verify(buffer, len, offset);
953         });
954     if (ret != PKG_SUCCESS) {
955         PKG_LOGE("Fail Decompress for %s", fileName_.c_str());
956         return ret;
957     }
958     PKG_LOGI("Unpack %s data offset:%zu packedSize:%zu unpackedSize:%zu", fileName_.c_str(), dataOffset_,
959         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize);
960     outStream->Flush(fileInfo_.fileInfo.unpackedSize);
961     return PKG_SUCCESS;
962 }
963 
Verify(PkgBuffer & buffer,size_t len,size_t offset)964 int32_t UpgradeFileEntry::Verify(PkgBuffer &buffer, size_t len, size_t offset)
965 {
966     UpgradePkgFile *pkgFile = static_cast<UpgradePkgFile*>(GetPkgFile());
967     if (pkgFile == nullptr) {
968         PKG_LOGE("Get pkg file ptr fail: %s", fileName_.c_str());
969         return PKG_INVALID_PARAM;
970     }
971 
972     if (pkgFile->GetImgHashData() == nullptr) {
973         return PKG_SUCCESS;
974     }
975 
976     PkgManager::StreamPtr stream = nullptr;
977     int32_t ret = pkgFile->GetPkgMgr()->CreatePkgStream(stream, fileName_, buffer);
978     if (stream == nullptr || ret != PKG_SUCCESS) {
979         PKG_LOGE("Failed to create stream");
980         return PKG_INVALID_PARAM;
981     }
982 
983     std::vector<uint8_t> hashVal;
984     ret = CalcSha256Digest(PkgStreamImpl::ConvertPkgStream(stream), len, hashVal);
985     if (ret != 0) {
986         PKG_LOGE("cal digest for pkg stream, buffer.length: %zu", buffer.length);
987         return PKG_INVALID_PARAM;
988     }
989 #ifndef DIFF_PATCH_SDK
990     size_t end = offset + len - 1;
991     bool checkRet = false;
992     if (pkgFile->GetUpgradeFileVer() >= UPGRADE_FILE_VERSION_V3) {
993         checkRet = CheckDataHashNew(pkgFile->GetImgHashData(), fileName_.c_str(),
994                                     offset, end, hashVal.data(), hashVal.size());
995     } else {
996         std::string imgName = fileName_ + (fileNum_ == 0 ? "" : std::to_string(fileNum_));
997         checkRet = check_data_hash(pkgFile->GetImgHashData(), imgName.c_str(),
998                                    offset, end, hashVal.data(), hashVal.size());
999     }
1000     if (!checkRet) {
1001         PKG_LOGE("check image hash value fail, name: %s, offset: %zu, end: %u", fileName_.c_str(), offset, end);
1002         return PKG_INVALID_PARAM;
1003     }
1004 #endif
1005     return PKG_SUCCESS;
1006 }
1007 
GetPackageTlvType()1008 int16_t UpgradePkgFile::GetPackageTlvType()
1009 {
1010     static int16_t packageTlvType[PKG_DIGEST_TYPE_MAX] = {
1011         TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA384
1012     };
1013     if (pkgInfo_.pkgInfo.digestMethod < PKG_DIGEST_TYPE_MAX) {
1014         return packageTlvType[pkgInfo_.pkgInfo.digestMethod];
1015     }
1016     return TLV_TYPE_FOR_SHA256;
1017 }
1018 } // namespace Hpackage
1019