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