• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "pkg_upgradefile.h"
16 #include <cerrno>
17 #include <cstdio>
18 #include <cstring>
19 #include <ctime>
20 #include <limits>
21 #include <memory>
22 #include "pkg_lz4file.h"
23 #include "pkg_manager.h"
24 #include "pkg_pkgfile.h"
25 #include "pkg_stream.h"
26 #include "pkg_utils.h"
27 #include "pkg_zipfile.h"
28 #include "securec.h"
29 
30 #define CHECK_TLV(tlv, tlvType, len, fileLen)                                                    \
31     do {                                                                                         \
32         if (!((tlv)->length < (fileLen) && (tlv)->length >= (len) && (tlv)->type == (tlvType) && \
33               ((tlv)->length + sizeof(PkgTlv)) < (fileLen))) {                                   \
34             PKG_LOGE("Invalid tlv type: %d length %u ", tlvType, ((tlv)->length));               \
35             return PKG_INVALID_FILE;                                                             \
36         }                                                                                        \
37     } while (0)
38 
39 using namespace std;
40 
41 namespace hpackage {
42 constexpr int32_t UPGRADE_FILE_HEADER_LEN = 3 * sizeof(PkgTlv) + sizeof(UpgradePkgHeader) + sizeof(UpgradePkgTime);
43 constexpr int32_t UPGRADE_RESERVE_LEN = 16;
44 constexpr int16_t TLV_TYPE_FOR_SHA256 = 0x0001;
45 constexpr int16_t TLV_TYPE_FOR_SHA384 = 0x0011;
46 constexpr size_t BUFFER_SIZE = 4 * 1024 * 1024;
47 
Init(const PkgManager::FileInfoPtr fileInfo,PkgStreamPtr inStream)48 int32_t UpgradeFileEntry::Init(const PkgManager::FileInfoPtr fileInfo, PkgStreamPtr inStream)
49 {
50     int32_t ret = PkgEntry::Init(&fileInfo_.fileInfo, fileInfo, inStream);
51     PKG_CHECK(ret == PKG_SUCCESS, return PKG_INVALID_PARAM, "Fail to check input param");
52     ComponentInfo *info = (ComponentInfo *)fileInfo;
53     if (info != nullptr) {
54         fileInfo_.version = info->version;
55         fileInfo_.id = info->id;
56         fileInfo_.resType = info->resType;
57         fileInfo_.type = info->type;
58         fileInfo_.compFlags = info->compFlags;
59         fileInfo_.originalSize = info->originalSize;
60         PKG_CHECK(!memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), info->digest, sizeof(info->digest)),
61             return PKG_NONE_MEMORY, "UpgradeFileEntry memcpy failed");
62     }
63     return PKG_SUCCESS;
64 }
65 
GetUpgradeSignatureLen() const66 size_t UpgradePkgFile::GetUpgradeSignatureLen() const
67 {
68     return SIGN_SHA256_LEN + SIGN_SHA384_LEN;
69 }
70 
GetDigestLen() const71 size_t UpgradePkgFile::GetDigestLen() const
72 {
73     return DigestAlgorithm::GetDigestLen(pkgInfo_.pkgInfo.digestMethod);
74 }
75 
AddEntry(const PkgManager::FileInfoPtr file,const PkgStreamPtr inStream)76 int32_t UpgradePkgFile::AddEntry(const PkgManager::FileInfoPtr file, const PkgStreamPtr inStream)
77 {
78     PKG_CHECK(file != nullptr && inStream != nullptr, return PKG_INVALID_PARAM, "Fail to check input param");
79     PKG_CHECK(CheckState({PKG_FILE_STATE_IDLE, PKG_FILE_STATE_WORKING}, PKG_FILE_STATE_WORKING),
80         return PKG_INVALID_STATE, "error state curr %d ", state_);
81     PKG_CHECK(pkgEntryMapId_.size() < pkgInfo_.pkgInfo.entryCount, return PKG_INVALID_PARAM,
82         "More entry for and for %s %zu", file->identity.c_str(), pkgEntryMapId_.size());
83     PKG_LOGI("Add file %s to package", file->identity.c_str());
84 
85     size_t compDataLen = 0;
86     for (auto &it : pkgEntryMapId_) {
87         compDataLen += (*it.second).GetFileInfo()->packedSize;
88     }
89 
90     UpgradeFileEntry *entry = static_cast<UpgradeFileEntry *>(AddPkgEntry(file->identity));
91     PKG_CHECK(entry != nullptr, return PKG_NONE_MEMORY, "Fail create pkg node for %s", file->identity.c_str());
92     int32_t ret = entry->Init(file, inStream);
93     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail init entry for %s", file->identity.c_str());
94 
95     size_t dataOffset = UPGRADE_FILE_HEADER_LEN + pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo);
96     dataOffset += UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen();
97     dataOffset += compDataLen;
98     size_t encodeLen = 0;
99     ret = entry->Pack(inStream, dataOffset, encodeLen);
100     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Pack for %s", file->identity.c_str());
101     packedFileSize_ += encodeLen;
102 
103     size_t offset = UPGRADE_FILE_HEADER_LEN + (pkgEntryMapId_.size() - 1) * sizeof(UpgradeCompInfo);
104     ret = entry->EncodeHeader(inStream, offset, encodeLen);
105     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail encode header for %s", file->identity.c_str());
106 
107     PKG_LOGI("Header offset:%zu data offset:%zu packedFileSize: %zu", offset, dataOffset, packedFileSize_);
108     return PKG_SUCCESS;
109 }
110 
SavePackage(size_t & signOffset)111 int32_t UpgradePkgFile::SavePackage(size_t &signOffset)
112 {
113     PKG_LOGI("SavePackage %s", pkgStream_->GetFileName().c_str());
114     PKG_CHECK(CheckState({PKG_FILE_STATE_WORKING}, PKG_FILE_STATE_CLOSE),
115         return PKG_INVALID_STATE, "error state curr %d ", state_);
116     // Allocate buffer size with max possible size
117     size_t buffSize = GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN;
118     buffSize = ((UPGRADE_FILE_HEADER_LEN > buffSize) ? UPGRADE_FILE_HEADER_LEN : buffSize);
119     std::vector<uint8_t> buffer(buffSize);
120 
121     size_t offset = 0;
122     // Package header information
123     WriteLE16(buffer.data(), GetPackageTlvType()); // Type is 1 for package header in TLV format
124     WriteLE16(buffer.data() + sizeof(uint16_t), sizeof(UpgradePkgHeader));
125     offset += sizeof(PkgTlv);
126     UpgradePkgHeader *header = reinterpret_cast<UpgradePkgHeader *>(buffer.data() + offset);
127     header->pkgInfoLength = sizeof(PkgTlv) + sizeof(PkgTlv) + sizeof(PkgTlv) + sizeof(UpgradePkgHeader) +
128         sizeof(UpgradePkgTime) + pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo) + UPGRADE_RESERVE_LEN;
129     WriteLE32(reinterpret_cast<uint8_t *>(&header->updateFileVersion), pkgInfo_.updateFileVersion);
130     int32_t ret = memcpy_s(header->softwareVersion, sizeof(header->softwareVersion), pkgInfo_.softwareVersion.data(),
131         pkgInfo_.softwareVersion.size());
132     PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret:%d", pkgStream_->GetFileName().c_str(), ret);
133     ret = memcpy_s(header->productUpdateId, sizeof(header->productUpdateId), pkgInfo_.productUpdateId.data(),
134         pkgInfo_.productUpdateId.size());
135     PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret:%d", pkgStream_->GetFileName().c_str(), ret);
136     offset += sizeof(UpgradePkgHeader);
137     // 时间tlv
138     WriteLE16(buffer.data() + offset, 0x02); // Type is 2 for time in TLV format
139     WriteLE16(buffer.data() + offset + sizeof(uint16_t), sizeof(UpgradePkgTime));
140     offset += sizeof(PkgTlv);
141     UpgradePkgTime *time = reinterpret_cast<UpgradePkgTime *>(buffer.data() + offset);
142     ret = memcpy_s(time->date, sizeof(time->date), pkgInfo_.date.data(), pkgInfo_.date.size());
143     PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret:%d", pkgStream_->GetFileName().c_str(), ret);
144     ret = memcpy_s(time->time, sizeof(time->time), pkgInfo_.time.data(), pkgInfo_.time.size());
145     PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret:%d", pkgStream_->GetFileName().c_str(), ret);
146     offset += sizeof(UpgradePkgTime);
147     // 组件的tlv
148     WriteLE16(buffer.data() + offset, 0x05); // Type is 5 for component in TLV format
149     WriteLE16(buffer.data() + offset + sizeof(uint16_t), pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo));
150     offset += sizeof(PkgTlv);
151     ret = pkgStream_->Write(buffer, UPGRADE_FILE_HEADER_LEN, 0);
152     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail write upgrade file header for %s ret:%d",
153         pkgStream_->GetFileName().c_str(), ret);
154 
155     // Clear buffer and save signature information
156     offset += pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo);
157     signOffset = offset + UPGRADE_RESERVE_LEN;
158 
159     buffer.assign(buffer.capacity(), 0);
160     size_t nameLen = 0;
161     ret = PkgFile::ConvertStringToBuffer(pkgInfo_.descriptPackageId, {buffer.data(), UPGRADE_RESERVE_LEN}, nameLen);
162     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail write descriptPackageId");
163     ret = pkgStream_->Write(buffer, GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN, offset);
164     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail write sign for %s", pkgStream_->GetFileName().c_str());
165     PKG_LOGI("SavePackage success file length: %zu signOffset %zu", pkgStream_->GetFileLength(), signOffset);
166     pkgStream_->Flush(offset);
167     return PKG_SUCCESS;
168 }
169 
LoadPackage(std::vector<std::string> & fileNames,VerifyFunction verifier)170 int32_t UpgradePkgFile::LoadPackage(std::vector<std::string> &fileNames, VerifyFunction verifier)
171 {
172     PKG_CHECK(verifier != nullptr, return PKG_INVALID_SIGNATURE, "Check verifier nullptr");
173     PKG_CHECK(CheckState({PKG_FILE_STATE_IDLE}, PKG_FILE_STATE_WORKING),
174         return PKG_INVALID_STATE, "error state curr %d ", state_);
175     PKG_LOGI("LoadPackage %s ", pkgStream_->GetFileName().c_str());
176     size_t fileLen = pkgStream_->GetFileLength();
177     // Allocate buffer with smallest package size
178     size_t buffSize = UPGRADE_FILE_HEADER_LEN + sizeof(UpgradeCompInfo) +
179         GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN;
180     PKG_CHECK(fileLen > 0 && fileLen <= static_cast<size_t>(0xffffffff) && fileLen >= buffSize,
181         return PKG_INVALID_FILE, "Invalid file %s fileLen:%zu ", pkgStream_->GetFileName().c_str(), fileLen);
182 
183     DigestAlgorithm::DigestAlgorithmPtr algorithm = nullptr;
184     // Parse header
185     PkgBuffer buffer(buffSize);
186     size_t parsedLen = 0;
187     int32_t ret = ReadUpgradePkgHeader(buffer, parsedLen, algorithm);
188     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Decode header fail %d", ret);
189 
190     ret = ReadComponents(buffer, parsedLen, algorithm, fileNames);
191     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Decode components fail %d", ret);
192     PKG_CHECK(parsedLen + UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen() < fileLen,
193         return ret, "Decode components fail %d", ret);
194 
195     // Read signature information
196     size_t readBytes = 0;
197     ret = pkgStream_->Read(buffer, parsedLen, GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN, readBytes);
198     PKG_CHECK(ret == PKG_SUCCESS, return ret, "read sign data fail");
199     PkgFile::ConvertBufferToString(pkgInfo_.descriptPackageId, {buffer.buffer, UPGRADE_RESERVE_LEN});
200     std::vector<uint8_t> signData;
201     if (pkgInfo_.pkgInfo.digestMethod == PKG_DIGEST_TYPE_SHA384) {
202         signData.resize(SIGN_SHA384_LEN);
203         ret = memcpy_s(signData.data(), signData.size(),
204             buffer.buffer + UPGRADE_RESERVE_LEN + SIGN_SHA256_LEN, SIGN_SHA384_LEN);
205     } else {
206         signData.resize(SIGN_SHA256_LEN);
207         ret = memcpy_s(signData.data(), signData.size(), buffer.buffer + UPGRADE_RESERVE_LEN, SIGN_SHA256_LEN);
208     }
209     PKG_CHECK(ret == PKG_SUCCESS, return ret, "memcpy sign data fail");
210     ret = memset_s(buffer.buffer + UPGRADE_RESERVE_LEN, buffer.length, 0, GetUpgradeSignatureLen());
211     PKG_CHECK(ret == 0, return ret, "memset buff fail");
212     algorithm->Update(buffer, UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen());
213     parsedLen += UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen();
214 
215     // Calculate digest and verify
216     return Verify(parsedLen, algorithm, verifier, signData);
217 }
218 
Verify(size_t start,DigestAlgorithm::DigestAlgorithmPtr algorithm,VerifyFunction verifier,const std::vector<uint8_t> & signData)219 int32_t UpgradePkgFile::Verify(size_t start, DigestAlgorithm::DigestAlgorithmPtr algorithm,
220     VerifyFunction verifier, const std::vector<uint8_t> &signData)
221 {
222     int ret = 0;
223     size_t buffSize = BUFFER_SIZE;
224     size_t offset = start;
225     size_t readBytes = 0;
226     PkgBuffer buffer(buffSize);
227 
228     while (offset + readBytes < pkgStream_->GetFileLength()) {
229         offset += readBytes;
230         readBytes = 0;
231         size_t remainBytes = pkgStream_->GetFileLength() - offset;
232         remainBytes = ((remainBytes > buffSize) ? buffSize : remainBytes);
233         ret = pkgStream_->Read(buffer, offset, remainBytes, readBytes);
234         PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to read data ");
235         algorithm->Update(buffer, readBytes);
236         pkgManager_->PostDecodeProgress(POST_TYPE_VERIFY_PKG, remainBytes, nullptr);
237     }
238 
239     PkgBuffer digest(GetDigestLen());
240     algorithm->Final(digest);
241     ret = verifier(&pkgInfo_.pkgInfo, digest.data, signData);
242     PKG_CHECK(ret == 0, return PKG_INVALID_SIGNATURE, "Fail to verifier signature");
243     return 0;
244 }
245 
ReadComponents(const PkgBuffer & buffer,size_t & parsedLen,DigestAlgorithm::DigestAlgorithmPtr algorithm,std::vector<std::string> & fileNames)246 int32_t UpgradePkgFile::ReadComponents(const PkgBuffer &buffer, size_t &parsedLen,
247     DigestAlgorithm::DigestAlgorithmPtr algorithm, std::vector<std::string> &fileNames)
248 {
249     size_t fileLen = pkgStream_->GetFileLength();
250     size_t readLen = 0;
251     int32_t ret = pkgStream_->Read(buffer, parsedLen, buffer.length, readLen);
252     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Read component fail");
253     PkgTlv tlv;
254     tlv.type = ReadLE16(buffer.buffer);
255     tlv.length = ReadLE16(buffer.buffer + sizeof(uint16_t));
256     CHECK_TLV(&tlv, 5, sizeof(UpgradeCompInfo), fileLen); // component type is 5
257     algorithm->Update(buffer, sizeof(PkgTlv)); // tlv generate digest
258 
259     parsedLen += sizeof(PkgTlv);
260     size_t dataOffset = parsedLen + tlv.length + GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN;
261     size_t srcOffset = 0;
262     size_t currLen = sizeof(PkgTlv);
263     while (srcOffset < tlv.length) {
264         if (currLen + sizeof(UpgradeCompInfo) > readLen) {
265             readLen = 0;
266             ret = pkgStream_->Read(buffer, parsedLen + srcOffset, buffer.length, readLen);
267             PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to read data");
268             currLen = 0;
269         }
270 
271         UpgradeFileEntry *entry = new UpgradeFileEntry(this, nodeId_++);
272         PKG_CHECK(entry != nullptr, return PKG_NONE_MEMORY, "Fail create upgrade node for %s",
273             pkgStream_->GetFileName().c_str());
274 
275         // Extract header information from file
276         size_t decodeLen = 0;
277         PkgBuffer headerBuff(buffer.buffer + currLen, readLen - currLen);
278         ret = entry->DecodeHeader(headerBuff, parsedLen + srcOffset, dataOffset, decodeLen);
279         PKG_CHECK(ret == PKG_SUCCESS, delete entry; return ret, "Fail to decode header");
280 
281         // Save entry
282         pkgEntryMapId_.insert(pair<uint32_t, PkgEntryPtr>(entry->GetNodeId(), entry));
283         pkgEntryMapFileName_.insert(std::pair<std::string, PkgEntryPtr>(entry->GetFileName(), entry));
284         fileNames.push_back(entry->GetFileName());
285 
286         PkgBuffer signBuffer(buffer.buffer + currLen, decodeLen);
287         algorithm->Update(signBuffer, decodeLen); // Generate digest for components
288 
289         currLen += decodeLen;
290         srcOffset += decodeLen;
291         PKG_CHECK(entry->GetFileInfo() != nullptr, delete entry; return PKG_INVALID_FILE, "Failed to get file info");
292         dataOffset += entry->GetFileInfo()->packedSize;
293         pkgInfo_.pkgInfo.entryCount++;
294         PKG_LOGI("Component packedSize %zu unpackedSize %zu %s", entry->GetFileInfo()->packedSize,
295             entry->GetFileInfo()->unpackedSize, entry->GetFileInfo()->identity.c_str());
296     }
297     parsedLen += srcOffset;
298     return PKG_SUCCESS;
299 }
300 
ReadUpgradePkgHeader(const PkgBuffer & buffer,size_t & realLen,DigestAlgorithm::DigestAlgorithmPtr & algorithm)301 int32_t UpgradePkgFile::ReadUpgradePkgHeader(const PkgBuffer &buffer, size_t &realLen,
302     DigestAlgorithm::DigestAlgorithmPtr &algorithm)
303 {
304     size_t fileLen = pkgStream_->GetFileLength();
305     size_t readLen = 0;
306     size_t currLen = 0;
307     int32_t ret = pkgStream_->Read(buffer, 0, buffer.length, readLen);
308     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to read header");
309     pkgInfo_.pkgInfo.pkgType = PkgFile::PKG_TYPE_UPGRADE;
310     pkgInfo_.pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
311     pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256;
312 
313     PkgTlv tlv;
314     tlv.type = ReadLE16(buffer.buffer);
315     tlv.length = ReadLE16(buffer.buffer + sizeof(uint16_t));
316     if (tlv.type == TLV_TYPE_FOR_SHA384) {
317         pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA384;
318     }
319 
320     // Header information
321     currLen = sizeof(PkgTlv);
322     UpgradePkgHeader *header = reinterpret_cast<UpgradePkgHeader *>(buffer.buffer + currLen);
323     pkgInfo_.updateFileVersion = ReadLE32(buffer.buffer + currLen + offsetof(UpgradePkgHeader, updateFileVersion));
324     PkgFile::ConvertBufferToString(pkgInfo_.softwareVersion, {header->softwareVersion,
325         sizeof(header->softwareVersion)});
326     PkgFile::ConvertBufferToString(pkgInfo_.productUpdateId, {header->productUpdateId,
327         sizeof(header->productUpdateId)});
328 
329     algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(pkgInfo_.pkgInfo.digestMethod);
330     PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM,
331         "Invalid file %s", pkgStream_->GetFileName().c_str());
332     algorithm->Init();
333 
334     if (currLen + tlv.length >= readLen) { // Extra TLV information, read it.
335         realLen = currLen + tlv.length;
336         algorithm->Update(buffer, realLen);
337         ret = pkgStream_->Read(buffer, realLen, buffer.length, readLen);
338         PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to read header");
339         currLen = 0;
340     } else {
341         currLen += tlv.length;
342     }
343 
344     // Time information
345     tlv.type = ReadLE16(buffer.buffer + currLen);
346     tlv.length = ReadLE16(buffer.buffer + currLen + sizeof(uint16_t));
347     CHECK_TLV(&tlv, sizeof(uint16_t), sizeof(UpgradePkgTime), fileLen);
348     currLen += sizeof(PkgTlv);
349     UpgradePkgTime *time = reinterpret_cast<UpgradePkgTime *>(buffer.buffer + currLen);
350     PkgFile::ConvertBufferToString(pkgInfo_.date, {time->date, sizeof(time->date)});
351     PkgFile::ConvertBufferToString(pkgInfo_.time, {time->time, sizeof(time->time)});
352     currLen += tlv.length;
353     realLen += currLen;
354 
355     // Parser header to get compressional algorithm
356     algorithm->Update(buffer, currLen); // Generate digest
357     return PKG_SUCCESS;
358 }
359 
EncodeHeader(PkgStreamPtr inStream,size_t startOffset,size_t & encodeLen)360 int32_t UpgradeFileEntry::EncodeHeader(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen)
361 {
362     PkgStreamPtr outStream = pkgFile_->GetPkgStream();
363     PKG_CHECK(outStream != nullptr && inStream != nullptr, return PKG_INVALID_PARAM,
364         "outStream or inStream null for %s", fileName_.c_str());
365 
366     UpgradeCompInfo comp;
367     PKG_CHECK(!memset_s(&comp, sizeof(comp), 0, sizeof(comp)),
368         return PKG_NONE_MEMORY, "UpgradeFileEntry memset_s failed");
369 
370     size_t len = 0;
371     int32_t ret = PkgFile::ConvertStringToBuffer(
372         fileInfo_.fileInfo.identity, {comp.address, sizeof(comp.address)}, len);
373     ret |= PkgFile::ConvertStringToBuffer(fileInfo_.version, {comp.version, sizeof(comp.version)}, len);
374     PKG_CHECK(ret == PKG_SUCCESS, return PKG_INVALID_PARAM, "outStream or inStream null for %s", fileName_.c_str());
375 
376     ret = memcpy_s(comp.digest, sizeof(comp.digest), fileInfo_.digest, sizeof(fileInfo_.digest));
377     PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret:%d", ret);
378     WriteLE32(reinterpret_cast<uint8_t *>(&comp.size), fileInfo_.fileInfo.unpackedSize);
379     WriteLE16(reinterpret_cast<uint8_t *>(&comp.id), fileInfo_.id);
380     WriteLE32(reinterpret_cast<uint8_t *>(&comp.originalSize), fileInfo_.originalSize);
381     comp.resType = fileInfo_.resType;
382     comp.flags = fileInfo_.compFlags;
383     comp.type = fileInfo_.type;
384 
385     headerOffset_ = startOffset;
386     PkgBuffer buffer(reinterpret_cast<uint8_t *>(&comp), sizeof(comp));
387     ret = outStream->Write(buffer, sizeof(comp), startOffset);
388     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail write header for %s", fileName_.c_str());
389     encodeLen = sizeof(UpgradeCompInfo);
390 
391     PKG_LOGI("EncodeHeader startOffset: %zu %zu packedSize:%zu %zu ", headerOffset_, dataOffset_,
392         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize);
393     return PKG_SUCCESS;
394 }
395 
Pack(PkgStreamPtr inStream,size_t startOffset,size_t & encodeLen)396 int32_t UpgradeFileEntry::Pack(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen)
397 {
398     PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo);
399     PkgStreamPtr outStream = pkgFile_->GetPkgStream();
400     PKG_CHECK(algorithm != nullptr && outStream != nullptr && inStream != nullptr, return PKG_INVALID_PARAM,
401         "outStream or inStream null for %s", fileName_.c_str());
402 
403     PkgAlgorithmContext context = {
404         {0, startOffset},
405         {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize},
406         0, fileInfo_.fileInfo.digestMethod
407     };
408     PKG_CHECK(!memcpy_s(context.digest, sizeof(context.digest), fileInfo_.digest, sizeof(fileInfo_.digest)),
409         return PKG_NONE_MEMORY, "UpgradeFileEntry pack memcpy failed");
410     int32_t ret = algorithm->Pack(inStream, outStream, context);
411     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Compress for %s", fileName_.c_str());
412 
413     // Fill digest and compressed size of file
414     PKG_CHECK(!memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), context.digest, sizeof(context.digest)),
415         return PKG_NONE_MEMORY, "UpgradeFileEntry pack memcpy failed");
416     fileInfo_.fileInfo.packedSize = context.packedSize;
417     dataOffset_ = startOffset;
418     encodeLen = fileInfo_.fileInfo.packedSize;
419     PKG_LOGI("Pack start:%zu unpackSize:%zu packSize:%zu", startOffset, fileInfo_.fileInfo.unpackedSize,
420         fileInfo_.fileInfo.packedSize);
421     return PKG_SUCCESS;
422 }
423 
DecodeHeader(const PkgBuffer & buffer,size_t headerOffset,size_t dataOffset,size_t & decodeLen)424 int32_t UpgradeFileEntry::DecodeHeader(const PkgBuffer &buffer, size_t headerOffset, size_t dataOffset,
425     size_t &decodeLen)
426 {
427     PkgStreamPtr inStream = pkgFile_->GetPkgStream();
428     PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, "outStream or inStream null for %s", fileName_.c_str());
429     PKG_CHECK(buffer.length >= sizeof(UpgradeCompInfo),
430         return PKG_INVALID_PKG_FORMAT, "Fail to check buffer %zu", buffer.length);
431 
432     UpgradeCompInfo *info = reinterpret_cast<UpgradeCompInfo *>(buffer.buffer);
433     fileInfo_.fileInfo.packedSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, size));
434     fileInfo_.fileInfo.unpackedSize = fileInfo_.fileInfo.packedSize;
435     fileInfo_.originalSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, originalSize));
436     fileInfo_.fileInfo.packMethod = PKG_COMPRESS_METHOD_NONE;
437     fileInfo_.fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE;
438     int32_t ret = memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), info->digest, sizeof(info->digest));
439     PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret:%d", ret);
440     PkgFile::ConvertBufferToString(fileInfo_.fileInfo.identity, {info->address, sizeof(info->address)});
441     PkgFile::ConvertBufferToString(fileInfo_.version, {info->version, sizeof(info->version)});
442     fileName_ = fileInfo_.fileInfo.identity;
443     fileInfo_.id = ReadLE16(buffer.buffer + offsetof(UpgradeCompInfo, id));
444     fileInfo_.resType = info->resType;
445     fileInfo_.compFlags = info->flags;
446     fileInfo_.type = info->type;
447 
448     headerOffset_ = headerOffset;
449     dataOffset_ = dataOffset;
450     decodeLen = sizeof(UpgradeCompInfo);
451 
452     PKG_LOGI("Component offset: %zu %zu packedSize:%zu %zu %s", headerOffset, dataOffset,
453         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize, fileName_.c_str());
454     return PKG_SUCCESS;
455 }
456 
Unpack(PkgStreamPtr outStream)457 int32_t UpgradeFileEntry::Unpack(PkgStreamPtr outStream)
458 {
459     PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo);
460     PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, "can not algorithm for %s", fileName_.c_str());
461 
462     PkgStreamPtr inStream = pkgFile_->GetPkgStream();
463     PKG_CHECK(outStream != nullptr && inStream != nullptr, return PKG_INVALID_PARAM,
464         "outStream or inStream null for %s", fileName_.c_str());
465     PkgAlgorithmContext context = {
466         {this->dataOffset_, 0},
467         {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize},
468         0, fileInfo_.fileInfo.digestMethod
469     };
470     int32_t ret = memcpy_s(context.digest, sizeof(context.digest), fileInfo_.digest, sizeof(fileInfo_.digest));
471     PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret:%d", ret);
472     ret = algorithm->Unpack(inStream, outStream, context);
473     PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", fileName_.c_str());
474     PKG_LOGI("Unpack %s data offset:%zu packedSize:%zu unpackedSize:%zu", fileName_.c_str(), dataOffset_,
475         fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize);
476     outStream->Flush(fileInfo_.fileInfo.unpackedSize);
477     return PKG_SUCCESS;
478 }
479 
GetPackageTlvType()480 int16_t UpgradePkgFile::GetPackageTlvType()
481 {
482     static int16_t packageTlvType[PKG_DIGEST_TYPE_MAX] = {
483         TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA256, TLV_TYPE_FOR_SHA384
484     };
485     if (pkgInfo_.pkgInfo.digestMethod < PKG_DIGEST_TYPE_MAX) {
486         return packageTlvType[pkgInfo_.pkgInfo.digestMethod];
487     }
488     return TLV_TYPE_FOR_SHA256;
489 }
490 } // namespace hpackage
491