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     size_t readBytes = 0;
268     size_t signLen = parsedLen;
269     PkgBuffer buffer(HASH_TLV_SIZE);
270     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, readBytes);
271     if (ret != PKG_SUCCESS) {
272         PKG_LOGE("read sign data fail");
273         UPDATER_LAST_WORD(ret, parsedLen);
274         return ret;
275     }
276     parsedLen += buffer.length;
277     uint16_t dataType = ReadLE16(buffer.buffer);
278     uint32_t dataLen = ReadLE32(buffer.buffer + sizeof(uint16_t));
279     if (dataType != TLV_TYPE_FOR_SIGN) {
280         PKG_LOGE("Invalid tlv type: %hu length %u ", dataType, dataLen);
281         UPDATER_LAST_WORD(ret, dataType);
282         return PKG_INVALID_FILE;
283     }
284 
285     PkgBuffer signBuf(dataLen);
286     ret = pkgStream_->Read(signBuf, parsedLen, signBuf.length, readBytes);
287     if (ret != PKG_SUCCESS) {
288         PKG_LOGE("read hash data fail");
289         UPDATER_LAST_WORD(ret, parsedLen);
290         return ret;
291     }
292     parsedLen += signBuf.length;
293     signData.resize(dataLen);
294     signData.assign(signBuf.data.begin(), signBuf.data.end());
295 
296     // refresh component data offset
297     signLen = parsedLen - signLen;
298     for (auto &it : pkgEntryMapId_) {
299         if (it.second != nullptr) {
300             it.second->AddDataOffset(signLen);
301         }
302     }
303     return PKG_SUCCESS;
304 }
305 
ReadImgHashTLV(std::vector<uint8_t> & imgHashBuf,size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,uint32_t needType)306 int32_t UpgradePkgFile::ReadImgHashTLV(std::vector<uint8_t> &imgHashBuf, size_t &parsedLen,
307                                        DigestAlgorithm::DigestAlgorithmPtr algorithm, uint32_t needType)
308 {
309     size_t readBytes = 0;
310     PkgBuffer buffer(HASH_TLV_SIZE);
311     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, readBytes);
312     if (ret != PKG_SUCCESS) {
313         PKG_LOGE("read image hash header fail");
314         UPDATER_LAST_WORD(ret);
315         return ret;
316     }
317 
318     parsedLen += buffer.length;
319     uint16_t type = ReadLE16(buffer.buffer);
320     uint32_t len = ReadLE32(buffer.buffer + sizeof(uint16_t));
321     if (type != needType) {
322         PKG_LOGE("Invalid tlv type: %d length %u ", type, len);
323         return PKG_INVALID_FILE;
324     }
325     algorithm->Update(buffer, buffer.length);
326     imgHashBuf.insert(imgHashBuf.end(), buffer.data.begin(), buffer.data.end());
327 
328     PkgBuffer dataBuf(len);
329     ret = pkgStream_->Read(dataBuf, parsedLen, dataBuf.length, readBytes);
330     if (ret != PKG_SUCCESS) {
331         PKG_LOGE("read hash data fail");
332         UPDATER_LAST_WORD(ret);
333         return ret;
334     }
335     parsedLen += dataBuf.length;
336     algorithm->Update(dataBuf, dataBuf.length);
337     imgHashBuf.insert(imgHashBuf.end(), dataBuf.data.begin(), dataBuf.data.end());
338     return PKG_SUCCESS;
339 }
340 
ReadImgHashData(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm)341 int32_t UpgradePkgFile::ReadImgHashData(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm)
342 {
343 #ifndef DIFF_PATCH_SDK
344     if ((!Updater::Utils::CheckUpdateMode(Updater::SDCARD_MODE) &&
345         !Updater::Utils::CheckUpdateMode(Updater::USB_MODE) &&
346         !Updater::Utils::CheckUpdateMode(Updater::SDCARD_INTRAL_MODE)) ||
347         pkgInfo_.updateFileVersion < UPGRADE_FILE_VERSION_V2) {
348         PKG_LOGI("ignore image hash check");
349         return PKG_SUCCESS;
350     }
351 #endif
352 
353     std::vector<uint8_t> imgHashBuf;
354     // read hash header
355     int32_t ret = ReadImgHashTLV(imgHashBuf, parsedLen, algorithm, TLV_TYPE_FOR_HASH_HEADER);
356     if (ret != PKG_SUCCESS) {
357         PKG_LOGE("read image hash info fail");
358         UPDATER_LAST_WORD(ret);
359         return ret;
360     }
361 
362     // read hash data
363     ret = ReadImgHashTLV(imgHashBuf, parsedLen, algorithm, TLV_TYPE_FOR_HASH_DATA);
364     if (ret != PKG_SUCCESS) {
365         PKG_LOGE("read image hash data fail");
366         UPDATER_LAST_WORD(ret);
367         return ret;
368     }
369 
370     // refresh component data offset
371     for (auto &it : pkgEntryMapId_) {
372         it.second->AddDataOffset(imgHashBuf.size());
373     }
374 
375 #ifndef DIFF_PATCH_SDK
376     if (pkgInfo_.updateFileVersion >= UPGRADE_FILE_VERSION_V3) {
377         hashCheck_ = LoadImgHashDataNew(imgHashBuf.data(), imgHashBuf.size());
378     } else {
379         hashCheck_ = LoadImgHashData(imgHashBuf.data(), imgHashBuf.size());
380     }
381     if (hashCheck_ == nullptr) {
382         PKG_LOGE("pause hash data fail");
383         return PKG_INVALID_FILE;
384     }
385 #endif
386 
387     return PKG_SUCCESS;
388 }
389 
ReadPackageInfo(std::vector<uint8_t> & signData,size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm)390 int32_t UpgradePkgFile::ReadPackageInfo(std::vector<uint8_t> &signData, size_t &parsedLen,
391     DigestAlgorithm::DigestAlgorithmPtr algorithm)
392 {
393     PkgBuffer buffer(GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN);
394     size_t readBytes = 0;
395     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, readBytes);
396     if (ret != PKG_SUCCESS) {
397         PKG_LOGE("read sign data fail");
398         UPDATER_LAST_WORD(ret);
399         return ret;
400     }
401 
402     PkgFileImpl::ConvertBufferToString(pkgInfo_.descriptPackageId, {buffer.buffer, UPGRADE_RESERVE_LEN});
403     if (pkgInfo_.pkgInfo.digestMethod == PKG_DIGEST_TYPE_SHA384) {
404         signData.resize(SIGN_SHA384_LEN);
405         ret = memcpy_s(signData.data(), signData.size(),
406             buffer.buffer + UPGRADE_RESERVE_LEN + SIGN_SHA256_LEN, SIGN_SHA384_LEN);
407     } else {
408         signData.resize(SIGN_SHA256_LEN);
409         ret = memcpy_s(signData.data(), signData.size(), buffer.buffer + UPGRADE_RESERVE_LEN, SIGN_SHA256_LEN);
410     }
411     if (ret != EOK) {
412         PKG_LOGE("memcpy sign data fail");
413         UPDATER_LAST_WORD(PKG_NONE_MEMORY);
414         return PKG_NONE_MEMORY;
415     }
416 
417     // refresh component data offset
418     for (auto &it : pkgEntryMapId_) {
419         if (it.second != nullptr) {
420             it.second->AddDataOffset(GetUpgradeSignatureLen());
421         }
422     }
423 
424     ret = memset_s(buffer.buffer + UPGRADE_RESERVE_LEN, buffer.length, 0, GetUpgradeSignatureLen());
425     if (ret != EOK) {
426         PKG_LOGE("memset buff fail");
427         UPDATER_LAST_WORD(PKG_NONE_MEMORY);
428         return PKG_NONE_MEMORY;
429     }
430     algorithm->Update(buffer, UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen());
431     parsedLen += UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen();
432     return PKG_SUCCESS;
433 }
434 
LoadPackage(std::vector<std::string> & fileNames,VerifyFunction verifier)435 int32_t UpgradePkgFile::LoadPackage(std::vector<std::string> &fileNames, VerifyFunction verifier)
436 {
437     if (verifier == nullptr) {
438         PKG_LOGE("Check verifier nullptr");
439         UPDATER_LAST_WORD(PKG_INVALID_SIGNATURE);
440         return PKG_INVALID_SIGNATURE;
441     }
442     if (!CheckState({PKG_FILE_STATE_IDLE}, PKG_FILE_STATE_WORKING)) {
443         PKG_LOGE("error state curr %d ", state_);
444         UPDATER_LAST_WORD(PKG_INVALID_STATE);
445         return PKG_INVALID_STATE;
446     }
447     PKG_LOGI("LoadPackage %s ", pkgStream_->GetFileName().c_str());
448     size_t fileLen = pkgStream_->GetFileLength();
449     // Allocate buffer with smallest package size
450     size_t buffSize = UPGRADE_FILE_HEADER_LEN + sizeof(UpgradeCompInfo) +
451         GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN;
452     if (fileLen < buffSize) {
453         PKG_LOGE("Invalid file %s fileLen:%zu ", pkgStream_->GetFileName().c_str(), fileLen);
454         UPDATER_LAST_WORD(PKG_INVALID_STATE);
455         return PKG_INVALID_FILE;
456     }
457 
458     DigestAlgorithm::DigestAlgorithmPtr algorithm = nullptr;
459     // Parse header
460     size_t parsedLen = 0;
461     int32_t ret = ReadUpgradePkgHeader(parsedLen, algorithm);
462     if (ret != PKG_SUCCESS) {
463         PKG_LOGE("Decode header fail %d", ret);
464         UPDATER_LAST_WORD(PKG_INVALID_STATE);
465         return ret;
466     }
467 
468     ret = ReadComponents(parsedLen, algorithm, fileNames);
469     if (ret != PKG_SUCCESS) {
470         PKG_LOGE("Decode components fail %d", ret);
471         UPDATER_LAST_WORD(ret);
472         return ret;
473     }
474 
475     ret = VerifyFile(parsedLen, algorithm, verifier);
476     pkgInfo_.pkgInfo.updateFileHeadLen = parsedLen;
477     return ret;
478 }
479 
VerifyFile(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier)480 int32_t UpgradePkgFile::VerifyFile(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm,
481                                    VerifyFunction verifier)
482 {
483     if (pkgInfo_.updateFileVersion >= UPGRADE_FILE_VERSION_V2) {
484         return VerifyFileV2(parsedLen, algorithm, verifier);
485     }
486 
487     return VerifyFileV1(parsedLen, algorithm, verifier);
488 }
489 
VerifyFileV1(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier)490 int32_t UpgradePkgFile::VerifyFileV1(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm,
491                                      VerifyFunction verifier)
492 {
493     std::vector<uint8_t> signData;
494     // Read signature information
495     int32_t ret = ReadPackageInfo(signData, parsedLen, algorithm);
496     if (ret != PKG_SUCCESS) {
497         PKG_LOGE("ReadPackageInfo fail %d", ret);
498         return ret;
499     }
500     // Calculate digest and verify
501     return Verify(parsedLen, algorithm, verifier, signData);
502 }
503 
VerifyFileV2(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier)504 int32_t UpgradePkgFile::VerifyFileV2(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr algorithm,
505                                      VerifyFunction verifier)
506 {
507     int32_t ret = ReadReserveData(parsedLen, algorithm);
508     if (ret != PKG_SUCCESS) {
509         PKG_LOGE("ReadReserveData fail %d", ret);
510         return ret;
511     }
512 
513     // Read image hash information
514     ret = ReadImgHashData(parsedLen, algorithm);
515     if (ret != PKG_SUCCESS) {
516         PKG_LOGW("LoadImgHashData fail %d, ignore image hash check", ret);
517         return ret;
518     }
519 
520     // Read signature information
521     std::vector<uint8_t> signData;
522     ret = ReadSignData(signData, parsedLen, algorithm);
523     if (ret != PKG_SUCCESS) {
524         PKG_LOGE("ReadSignData fail %d", ret);
525         return ret;
526     }
527     return VerifyHeader(algorithm, verifier, signData);
528 }
529 
Verify(size_t start,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier,const std::vector<uint8_t> & signData)530 int32_t UpgradePkgFile::Verify(size_t start, DigestAlgorithm::DigestAlgorithmPtr algorithm,
531     VerifyFunction verifier, const std::vector<uint8_t> &signData)
532 {
533     Updater::UPDATER_INIT_RECORD;
534     int ret = 0;
535     size_t buffSize = BUFFER_SIZE;
536     size_t offset = start;
537     size_t readBytes = 0;
538     PkgBuffer buffer(buffSize);
539 
540     while (offset + readBytes < pkgStream_->GetFileLength()) {
541         offset += readBytes;
542         readBytes = 0;
543         size_t remainBytes = pkgStream_->GetFileLength() - offset;
544         remainBytes = ((remainBytes > buffSize) ? buffSize : remainBytes);
545         ret = pkgStream_->Read(buffer, offset, remainBytes, readBytes);
546         if (ret != PKG_SUCCESS) {
547             PKG_LOGE("Fail to read data ");
548             UPDATER_LAST_WORD(ret);
549             return ret;
550         }
551         algorithm->Update(buffer, readBytes);
552         pkgManager_->PostDecodeProgress(POST_TYPE_VERIFY_PKG, remainBytes, nullptr);
553     }
554 
555     PkgBuffer digest(GetDigestLen());
556     algorithm->Final(digest);
557     ret = verifier(&pkgInfo_.pkgInfo, digest.data, signData);
558     if (ret != 0) {
559         PKG_LOGE("Fail to verifier signature");
560         UPDATER_LAST_WORD(PKG_INVALID_SIGNATURE);
561         return PKG_INVALID_SIGNATURE;
562     }
563     return 0;
564 }
565 
VerifyHeader(DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier,const std::vector<uint8_t> & signData)566 int32_t UpgradePkgFile::VerifyHeader(DigestAlgorithm::DigestAlgorithmPtr algorithm,
567     VerifyFunction verifier, const std::vector<uint8_t> &signData)
568 {
569     Updater::UPDATER_INIT_RECORD;
570     PkgBuffer digest(GetDigestLen());
571     algorithm->Final(digest);
572     int ret = 0;
573     if (pkgInfo_.updateFileVersion >= UPGRADE_FILE_VERSION_V4) {
574         auto signature = signData;
575         PkgVerifyUtil pkgVerifyUtil;
576         ret = pkgVerifyUtil.VerifySign(signature, digest.data);
577     } else {
578         ret = verifier(&pkgInfo_.pkgInfo, digest.data, signData);
579     }
580     if (ret != 0) {
581         PKG_LOGE("Fail to verifier signature");
582         UPDATER_LAST_WORD(PKG_INVALID_SIGNATURE);
583         return PKG_INVALID_SIGNATURE;
584     }
585     return 0;
586 }
587 
SaveEntry(const PkgBuffer & buffer,size_t & parsedLen,UpgradeParam & info,DigestAlgorithm::DigestAlgorithmPtr algorithm,std::vector<std::string> & fileNames)588 int32_t UpgradePkgFile::SaveEntry(const PkgBuffer &buffer, size_t &parsedLen, UpgradeParam &info,
589     DigestAlgorithm::DigestAlgorithmPtr algorithm, std::vector<std::string> &fileNames)
590 {
591     UpgradeFileEntry *entry = new (std::nothrow) UpgradeFileEntry(this, nodeId_++);
592     if (entry == nullptr) {
593         PKG_LOGE("Fail create upgrade node for %s", pkgStream_->GetFileName().c_str());
594         return PKG_NONE_MEMORY;
595     }
596 
597     // Extract header information from file
598     size_t decodeLen = 0;
599     PkgBuffer headerBuff(buffer.buffer + info.currLen, info.readLen - info.currLen);
600     int32_t ret = entry->DecodeHeader(headerBuff, parsedLen + info.srcOffset, info.dataOffset, decodeLen);
601     if (ret != PKG_SUCCESS) {
602         delete entry;
603         PKG_LOGE("Fail to decode header");
604         return ret;
605     }
606     // Save entry
607     pkgEntryMapId_.insert(pair<uint32_t, PkgEntryPtr>(entry->GetNodeId(), entry));
608     pkgEntryMapFileName_.insert(std::pair<std::string, PkgEntryPtr>(entry->GetFileName(), entry));
609     fileNames.push_back(entry->GetFileName());
610 
611     PkgBuffer signBuffer(buffer.buffer + info.currLen, decodeLen);
612     algorithm->Update(signBuffer, decodeLen); // Generate digest for components
613 
614     info.currLen += decodeLen;
615     info.srcOffset += decodeLen;
616 
617     if (entry->GetFileInfo() == nullptr) {
618         delete entry;
619         PKG_LOGE("Failed to get file info");
620         return PKG_INVALID_FILE;
621     }
622 
623     info.dataOffset += entry->GetFileInfo()->packedSize;
624     pkgInfo_.pkgInfo.entryCount++;
625     PKG_LOGI("Component packedSize %zu unpackedSize %zu %s", entry->GetFileInfo()->packedSize,
626         entry->GetFileInfo()->unpackedSize, entry->GetFileInfo()->identity.c_str());
627     return PKG_SUCCESS;
628 }
629 
ReadComponents(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,std::vector<std::string> & fileNames)630 int32_t UpgradePkgFile::ReadComponents(size_t &parsedLen,
631     DigestAlgorithm::DigestAlgorithmPtr algorithm, std::vector<std::string> &fileNames)
632 {
633     Updater::UPDATER_INIT_RECORD;
634     UpgradeParam info;
635     size_t fileLen = pkgStream_->GetFileLength();
636     info.readLen = 0;
637     PkgBuffer buffer(sizeof(PkgTlv));
638     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, info.readLen);
639     if (ret != PKG_SUCCESS) {
640         PKG_LOGE("Read component fail");
641         UPDATER_LAST_WORD(ret);
642         return ret;
643     }
644     PkgTlv tlv;
645     tlv.type = ReadLE16(buffer.buffer);
646     tlv.length = ReadLE16(buffer.buffer + sizeof(uint16_t));
647     TLV_CHECK_AND_RETURN(&tlv, 5, sizeof(UpgradeCompInfo), fileLen); // component type is 5
648     algorithm->Update(buffer, sizeof(PkgTlv)); // tlv generate digest
649 
650     parsedLen += sizeof(PkgTlv);
651 
652     info.dataOffset = parsedLen + tlv.length + UPGRADE_RESERVE_LEN;
653     info.srcOffset = 0;
654     info.currLen = sizeof(PkgTlv);
655     PkgBuffer compBuffer(sizeof(UpgradeCompInfo));
656     while (info.srcOffset < tlv.length) {
657         if (info.currLen + sizeof(UpgradeCompInfo) > info.readLen) {
658             info.readLen = 0;
659             ret = pkgStream_->Read(compBuffer, parsedLen + info.srcOffset, compBuffer.length, info.readLen);
660             if (ret != PKG_SUCCESS) {
661                 PKG_LOGE("Fail to read data");
662                 UPDATER_LAST_WORD(ret);
663                 return ret;
664             }
665             info.currLen = 0;
666         }
667         ret = SaveEntry(compBuffer, parsedLen, info, algorithm, fileNames);
668         if (ret != PKG_SUCCESS) {
669             PKG_LOGE("SaveEntry");
670             UPDATER_LAST_WORD(ret);
671             return ret;
672         }
673     }
674     parsedLen += info.srcOffset;
675     return PKG_SUCCESS;
676 }
677 
ParsePkgHeaderToTlv(const PkgBuffer & buffer,size_t & currLen,PkgTlv & tlv)678 void UpgradePkgFile::ParsePkgHeaderToTlv(const PkgBuffer &buffer, size_t &currLen, PkgTlv &tlv)
679 {
680     pkgInfo_.pkgInfo.pkgType = PkgFile::PKG_TYPE_UPGRADE;
681     pkgInfo_.pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
682     pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256;
683 
684     tlv.type = ReadLE16(buffer.buffer);
685     tlv.length = ReadLE16(buffer.buffer + sizeof(uint16_t));
686     if (tlv.type == TLV_TYPE_FOR_SHA384) {
687         pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA384;
688     }
689 
690     // Header information
691     currLen = sizeof(PkgTlv);
692     UpgradePkgHeader *header = reinterpret_cast<UpgradePkgHeader *>(buffer.buffer + currLen);
693     pkgInfo_.updateFileVersion = ReadLE32(buffer.buffer + currLen + offsetof(UpgradePkgHeader, updateFileVersion));
694     PkgFileImpl::ConvertBufferToString(pkgInfo_.softwareVersion, {header->softwareVersion,
695         sizeof(header->softwareVersion)});
696     PkgFileImpl::ConvertBufferToString(pkgInfo_.productUpdateId, {header->productUpdateId,
697         sizeof(header->productUpdateId)});
698 }
699 
ReadReserveData(size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr & algorithm)700 int32_t UpgradePkgFile::ReadReserveData(size_t &parsedLen, DigestAlgorithm::DigestAlgorithmPtr &algorithm)
701 {
702     size_t readBytes = 0;
703     PkgBuffer reserve_buf(UPGRADE_RESERVE_LEN);
704     int32_t ret = pkgStream_->Read(reserve_buf, parsedLen, reserve_buf.length, readBytes);
705     if (ret != PKG_SUCCESS) {
706         PKG_LOGE("read reserve data fail");
707         UPDATER_LAST_WORD(ret);
708         return ret;
709     }
710     PkgFileImpl::ConvertBufferToString(pkgInfo_.descriptPackageId, {reserve_buf.buffer, UPGRADE_RESERVE_LEN});
711     algorithm->Update(reserve_buf, reserve_buf.length);
712     parsedLen += reserve_buf.length;
713     return PKG_SUCCESS;
714 }
715 
ReadUpgradePkgHeader(size_t & realLen,DigestAlgorithm::DigestAlgorithmPtr & algorithm)716 int32_t UpgradePkgFile::ReadUpgradePkgHeader(size_t &realLen, DigestAlgorithm::DigestAlgorithmPtr &algorithm)
717 {
718     Updater::UPDATER_INIT_RECORD;
719     size_t fileLen = pkgStream_->GetFileLength();
720     size_t readLen = 0;
721     size_t currLen = 0;
722     PkgTlv tlv;
723     PkgBuffer buffer(UPGRADE_FILE_BASIC_LEN);
724     int32_t ret = pkgStream_->Read(buffer, 0, buffer.length, readLen);
725     if (ret != PKG_SUCCESS) {
726         PKG_LOGE("Fail to read header");
727         UPDATER_LAST_WORD(ret);
728         return ret;
729     }
730 
731     ParsePkgHeaderToTlv(buffer, currLen, tlv);
732     algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(pkgInfo_.pkgInfo.digestMethod);
733     if (algorithm == nullptr) {
734         PKG_LOGE("Invalid file %s", pkgStream_->GetFileName().c_str());
735         UPDATER_LAST_WORD(PKG_NOT_EXIST_ALGORITHM);
736         return PKG_NOT_EXIST_ALGORITHM;
737     }
738     algorithm->Init();
739 
740     if (currLen + tlv.length >= readLen) { // Extra TLV information, read it.
741         realLen = currLen + tlv.length;
742         algorithm->Update(buffer, realLen);
743         ret = pkgStream_->Read(buffer, realLen, buffer.length, readLen);
744         if (ret != PKG_SUCCESS) {
745             PKG_LOGE("Fail to read header");
746             UPDATER_LAST_WORD(ret);
747             return ret;
748         }
749         currLen = 0;
750     } else {
751         currLen += tlv.length;
752     }
753     // Time information
754     tlv.type = ReadLE16(buffer.buffer + currLen);
755     tlv.length = ReadLE16(buffer.buffer + currLen + sizeof(uint16_t));
756     TLV_CHECK_AND_RETURN(&tlv, sizeof(uint16_t), sizeof(UpgradePkgTime), fileLen);
757     currLen += sizeof(PkgTlv);
758     UpgradePkgTime *time = reinterpret_cast<UpgradePkgTime *>(buffer.buffer + currLen);
759     PkgFileImpl::ConvertBufferToString(pkgInfo_.date, {time->date, sizeof(time->date)});
760     PkgFileImpl::ConvertBufferToString(pkgInfo_.time, {time->time, sizeof(time->time)});
761     currLen += tlv.length;
762     realLen += currLen;
763 
764     // Parser header to get compressional algorithm
765     algorithm->Update(buffer, currLen); // Generate digest
766     return PKG_SUCCESS;
767 }
768 
GetUpGradeCompInfo(UpgradeCompInfo & comp)769 int32_t UpgradeFileEntry::GetUpGradeCompInfo(UpgradeCompInfo &comp)
770 {
771     if (memset_s(&comp, sizeof(comp), 0, sizeof(comp)) != EOK) {
772         PKG_LOGE("UpgradeFileEntry memset_s failed");
773         return PKG_NONE_MEMORY;
774     }
775     size_t len = 0;
776     int32_t ret = PkgFileImpl::ConvertStringToBuffer(
777         fileInfo_.fileInfo.identity, {comp.address, sizeof(comp.address)}, 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 
783     ret = PkgFileImpl::ConvertStringToBuffer(fileInfo_.version, {comp.version, sizeof(comp.version)}, 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     ret = memcpy_s(comp.digest, sizeof(comp.digest), fileInfo_.digest, sizeof(fileInfo_.digest));
789     if (ret != EOK) {
790         PKG_LOGE("Fail to memcpy_s ret: %d", ret);
791         return ret;
792     }
793     return PKG_SUCCESS;
794 }
795 
EncodeHeader(PkgStreamPtr inStream,size_t startOffset,size_t & encodeLen)796 int32_t UpgradeFileEntry::EncodeHeader(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen)
797 {
798     PkgStreamPtr outStream = pkgFile_->GetPkgStream();
799     if (outStream == nullptr || inStream == nullptr) {
800         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
801         return PKG_INVALID_PARAM;
802     }
803 
804     UpgradeCompInfo comp;
805     int ret = GetUpGradeCompInfo(comp);
806     if (ret != PKG_SUCCESS) {
807         PKG_LOGE("GetUpGradeCompInfo failed");
808         return ret;
809     }
810 
811     WriteLE32(reinterpret_cast<uint8_t *>(&comp.size), fileInfo_.fileInfo.unpackedSize);
812     WriteLE16(reinterpret_cast<uint8_t *>(&comp.id), fileInfo_.id);
813     WriteLE32(reinterpret_cast<uint8_t *>(&comp.originalSize), fileInfo_.originalSize);
814     comp.resType = fileInfo_.resType;
815     comp.flags = fileInfo_.compFlags;
816     comp.type = fileInfo_.type;
817 
818     headerOffset_ = startOffset;
819     PkgBuffer buffer(reinterpret_cast<uint8_t *>(&comp), sizeof(comp));
820     ret = outStream->Write(buffer, sizeof(comp), startOffset);
821     if (ret != PKG_SUCCESS) {
822         PKG_LOGE("Fail write header for %s", fileName_.c_str());
823         return ret;
824     }
825     encodeLen = sizeof(UpgradeCompInfo);
826 
827     PKG_LOGI("EncodeHeader startOffset: %zu %zu packedSize:%zu %zu ", headerOffset_, dataOffset_,
828         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize);
829     return PKG_SUCCESS;
830 }
831 
Pack(PkgStreamPtr inStream,size_t startOffset,size_t & encodeLen)832 int32_t UpgradeFileEntry::Pack(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen)
833 {
834     PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo);
835     PkgStreamPtr outStream = pkgFile_->GetPkgStream();
836     if (algorithm == nullptr || outStream == nullptr || inStream == nullptr) {
837         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
838         return PKG_INVALID_PARAM;
839     }
840 
841     PkgAlgorithmContext context = {
842         {0, startOffset},
843         {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize},
844         0, fileInfo_.fileInfo.digestMethod
845     };
846     if (memcpy_s(context.digest, sizeof(context.digest), fileInfo_.digest, sizeof(fileInfo_.digest)) != EOK) {
847         PKG_LOGE("UpgradeFileEntry pack memcpy failed");
848         return PKG_NONE_MEMORY;
849     }
850     int32_t ret = algorithm->Pack(inStream, outStream, context);
851     if (ret != PKG_SUCCESS) {
852         PKG_LOGE("Fail Compress for %s", fileName_.c_str());
853         return ret;
854     }
855 
856     // Fill digest and compressed size of file
857     if (memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), context.digest, sizeof(context.digest)) != EOK) {
858         PKG_LOGE("UpgradeFileEntry pack memcpy failed");
859         return PKG_NONE_MEMORY;
860     }
861     fileInfo_.fileInfo.packedSize = context.packedSize;
862     dataOffset_ = startOffset;
863     encodeLen = fileInfo_.fileInfo.packedSize;
864     PKG_LOGI("Pack start:%zu unpackSize:%zu packSize:%zu", startOffset, fileInfo_.fileInfo.unpackedSize,
865         fileInfo_.fileInfo.packedSize);
866     return PKG_SUCCESS;
867 }
868 
DecodeHeader(PkgBuffer & buffer,size_t headerOffset,size_t dataOffset,size_t & decodeLen)869 int32_t UpgradeFileEntry::DecodeHeader(PkgBuffer &buffer, size_t headerOffset, size_t dataOffset,
870     size_t &decodeLen)
871 {
872     UpgradePkgFile *pkgFile = static_cast<UpgradePkgFile*>(GetPkgFile());
873     if (pkgFile == nullptr) {
874         PKG_LOGE("Get pkg file ptr fail");
875         return PKG_INVALID_PARAM;
876     }
877 
878     PkgStreamPtr inStream = pkgFile->GetPkgStream();
879     if (inStream == nullptr) {
880         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
881         return PKG_INVALID_PARAM;
882     }
883     if (buffer.length < sizeof(UpgradeCompInfo)) {
884         PKG_LOGE("Fail to check buffer %zu", buffer.length);
885         return PKG_INVALID_PKG_FORMAT;
886     }
887 
888     UpgradeCompInfo *info = reinterpret_cast<UpgradeCompInfo *>(buffer.buffer);
889     if (pkgFile->GetUpgradeFileVer() >= UPGRADE_FILE_VERSION_V3) {
890         fileInfo_.fileInfo.packedSize = ReadLE64(buffer.buffer + offsetof(UpgradeCompInfo, size));
891     } else {
892         fileInfo_.fileInfo.packedSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, size));
893         fileInfo_.originalSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, originalSize));
894     }
895     fileInfo_.fileInfo.unpackedSize = fileInfo_.fileInfo.packedSize;
896     fileInfo_.fileInfo.packMethod = PKG_COMPRESS_METHOD_NONE;
897     fileInfo_.fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE;
898     fileInfo_.fileInfo.resType = info->resType;
899     int32_t ret = memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), info->digest, sizeof(info->digest));
900     if (ret != EOK) {
901         PKG_LOGE("Fail to memcpy_s ret: %d", ret);
902         return ret;
903     }
904     PkgFileImpl::ConvertBufferToString(fileInfo_.fileInfo.identity, {info->address, sizeof(info->address)});
905     PkgFileImpl::ConvertBufferToString(fileInfo_.version, {info->version, sizeof(info->version)});
906     fileName_ = fileInfo_.fileInfo.identity;
907     fileInfo_.id = ReadLE16(buffer.buffer + offsetof(UpgradeCompInfo, id));
908     fileInfo_.resType = info->resType;
909     fileInfo_.compFlags = info->flags;
910     fileInfo_.type = info->type;
911 
912     headerOffset_ = headerOffset;
913     dataOffset_ = dataOffset;
914     decodeLen = sizeof(UpgradeCompInfo);
915 
916     PKG_LOGI("Component offset: %zu %zu packedSize:%zu %zu %s", headerOffset, dataOffset,
917         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize, fileName_.c_str());
918     return PKG_SUCCESS;
919 }
920 
Unpack(PkgStreamPtr outStream)921 int32_t UpgradeFileEntry::Unpack(PkgStreamPtr outStream)
922 {
923     PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo);
924     if (algorithm == nullptr) {
925         PKG_LOGE("can not algorithm for %s", fileName_.c_str());
926         return PKG_INVALID_PARAM;
927     }
928 
929     PkgStreamPtr inStream = pkgFile_->GetPkgStream();
930     if (outStream == nullptr || inStream == nullptr) {
931         PKG_LOGE("outStream or inStream null for %s", fileName_.c_str());
932         return PKG_INVALID_PARAM;
933     }
934     PkgAlgorithmContext context = {
935         {this->dataOffset_, 0},
936         {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize},
937         0, fileInfo_.fileInfo.digestMethod
938     };
939     int32_t ret = memcpy_s(context.digest, sizeof(context.digest), fileInfo_.digest, sizeof(fileInfo_.digest));
940     if (ret != EOK) {
941         PKG_LOGE("Fail to memcpy_s ret: %d", ret);
942         return ret;
943     }
944     ret = algorithm->UnpackWithVerify(inStream, outStream, context,
945         [this](PkgBuffer &buffer, size_t len, size_t offset) ->int32_t {
946             return Verify(buffer, len, offset);
947         });
948     if (ret != PKG_SUCCESS) {
949         PKG_LOGE("Fail Decompress for %s", fileName_.c_str());
950         return ret;
951     }
952     PKG_LOGI("Unpack %s data offset:%zu packedSize:%zu unpackedSize:%zu", fileName_.c_str(), dataOffset_,
953         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize);
954     outStream->Flush(fileInfo_.fileInfo.unpackedSize);
955     return PKG_SUCCESS;
956 }
957 
Verify(PkgBuffer & buffer,size_t len,size_t offset)958 int32_t UpgradeFileEntry::Verify(PkgBuffer &buffer, size_t len, size_t offset)
959 {
960     UpgradePkgFile *pkgFile = static_cast<UpgradePkgFile*>(GetPkgFile());
961     if (pkgFile == nullptr) {
962         PKG_LOGE("Get pkg file ptr fail: %s", fileName_.c_str());
963         return PKG_INVALID_PARAM;
964     }
965 
966     if (pkgFile->GetImgHashData() == nullptr) {
967         return PKG_SUCCESS;
968     }
969 
970     PkgManager::StreamPtr stream = nullptr;
971     int32_t ret = pkgFile->GetPkgMgr()->CreatePkgStream(stream, fileName_, buffer);
972     if (stream == nullptr || ret != PKG_SUCCESS) {
973         PKG_LOGE("Failed to create stream");
974         return PKG_INVALID_PARAM;
975     }
976 
977     std::vector<uint8_t> hashVal;
978     ret = CalcSha256Digest(PkgStreamImpl::ConvertPkgStream(stream), len, hashVal);
979     if (ret != 0) {
980         PKG_LOGE("cal digest for pkg stream, buffer.length: %zu", buffer.length);
981         return PKG_INVALID_PARAM;
982     }
983 #ifndef DIFF_PATCH_SDK
984     size_t end = offset + len - 1;
985     bool checkRet = false;
986     if (pkgFile->GetUpgradeFileVer() >= UPGRADE_FILE_VERSION_V3) {
987         checkRet = CheckDataHashNew(pkgFile->GetImgHashData(), fileName_.c_str(),
988                                     offset, end, hashVal.data(),  hashVal.size());
989     } else {
990         checkRet = check_data_hash(pkgFile->GetImgHashData(), fileName_.c_str(),
991                                    offset, end, hashVal.data(),  hashVal.size());
992     }
993     if (!checkRet) {
994         PKG_LOGE("check image hash value fail, name: %s, offset: %zu, end: %u", fileName_.c_str(), offset, end);
995         return PKG_INVALID_PARAM;
996     }
997 #endif
998     return PKG_SUCCESS;
999 }
1000 
GetPackageTlvType()1001 int16_t UpgradePkgFile::GetPackageTlvType()
1002 {
1003     static int16_t packageTlvType[PKG_DIGEST_TYPE_MAX] = {
1004         TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA384
1005     };
1006     if (pkgInfo_.pkgInfo.digestMethod < PKG_DIGEST_TYPE_MAX) {
1007         return packageTlvType[pkgInfo_.pkgInfo.digestMethod];
1008     }
1009     return TLV_TYPE_FOR_SHA256;
1010 }
1011 } // namespace Hpackage
1012