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