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