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