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