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