1fb299fa2Sopenharmony_ci/*
2fb299fa2Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at
6fb299fa2Sopenharmony_ci *
7fb299fa2Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb299fa2Sopenharmony_ci *
9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and
13fb299fa2Sopenharmony_ci * limitations under the License.
14fb299fa2Sopenharmony_ci */
15fb299fa2Sopenharmony_ci
16fb299fa2Sopenharmony_ci#include "patch/update_patch.h"
17fb299fa2Sopenharmony_ci#include <memory>
18fb299fa2Sopenharmony_ci#include <vector>
19fb299fa2Sopenharmony_ci#include "blocks_patch.h"
20fb299fa2Sopenharmony_ci#include "diffpatch.h"
21fb299fa2Sopenharmony_ci#include "image_patch.h"
22fb299fa2Sopenharmony_ci#include "openssl/sha.h"
23fb299fa2Sopenharmony_ci#include "securec.h"
24fb299fa2Sopenharmony_ci
25fb299fa2Sopenharmony_ciusing namespace Hpackage;
26fb299fa2Sopenharmony_cinamespace UpdatePatch {
27fb299fa2Sopenharmony_ciint32_t UpdateApplyPatch::ApplyImagePatch(const PatchParam &param, const std::vector<uint8_t> &bonusData,
28fb299fa2Sopenharmony_ci    ImageProcessor writer, const std::string& expected)
29fb299fa2Sopenharmony_ci{
30fb299fa2Sopenharmony_ci    if (writer == nullptr) {
31fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyImagePatch : processor is null");
32fb299fa2Sopenharmony_ci        return -1;
33fb299fa2Sopenharmony_ci    }
34fb299fa2Sopenharmony_ci    std::unique_ptr<ImagePatchWriter> patchWriter = std::make_unique<ImagePatchWriter>(writer, expected, "");
35fb299fa2Sopenharmony_ci    if (patchWriter == nullptr) {
36fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyImagePatch : Failed to create patch writer");
37fb299fa2Sopenharmony_ci        return -1;
38fb299fa2Sopenharmony_ci    }
39fb299fa2Sopenharmony_ci    int32_t ret = patchWriter->Init();
40fb299fa2Sopenharmony_ci    if (ret != 0) {
41fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyImagePatch : Failed to init patch writer");
42fb299fa2Sopenharmony_ci        return -1;
43fb299fa2Sopenharmony_ci    }
44fb299fa2Sopenharmony_ci    ret = ApplyImagePatch(param, patchWriter.get(), bonusData);
45fb299fa2Sopenharmony_ci    if (ret != 0) {
46fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyImagePatch : Failed to apply image patch");
47fb299fa2Sopenharmony_ci        return -1;
48fb299fa2Sopenharmony_ci    }
49fb299fa2Sopenharmony_ci    return patchWriter->Finish();
50fb299fa2Sopenharmony_ci}
51fb299fa2Sopenharmony_ci
52fb299fa2Sopenharmony_cibool UpdateApplyPatch::PreCheck(const PatchParam &param, const UpdatePatchWriterPtr writer)
53fb299fa2Sopenharmony_ci{
54fb299fa2Sopenharmony_ci    if (writer == nullptr) {
55fb299fa2Sopenharmony_ci        PATCH_LOGE("check param fail ");
56fb299fa2Sopenharmony_ci        return false;
57fb299fa2Sopenharmony_ci    }
58fb299fa2Sopenharmony_ci    if (param.patchSize < (std::char_traits<char>::length(PKGDIFF_MAGIC) + sizeof(int32_t))) {
59fb299fa2Sopenharmony_ci        PATCH_LOGE("patch too short to contain header ");
60fb299fa2Sopenharmony_ci        return false;
61fb299fa2Sopenharmony_ci    }
62fb299fa2Sopenharmony_ci    if (memcmp(param.patch, PKGDIFF_MAGIC, std::char_traits<char>::length(PKGDIFF_MAGIC)) != 0) {
63fb299fa2Sopenharmony_ci        PATCH_LOGE("corrupt patch file header (magic number) ");
64fb299fa2Sopenharmony_ci        return false;
65fb299fa2Sopenharmony_ci    }
66fb299fa2Sopenharmony_ci    return true;
67fb299fa2Sopenharmony_ci}
68fb299fa2Sopenharmony_ci
69fb299fa2Sopenharmony_ciint32_t UpdateApplyPatch::ApplyImagePatch(const PatchParam &param,
70fb299fa2Sopenharmony_ci    UpdatePatchWriterPtr writer, const std::vector<uint8_t> &bonusData)
71fb299fa2Sopenharmony_ci{
72fb299fa2Sopenharmony_ci    if (!PreCheck(param, writer)) {
73fb299fa2Sopenharmony_ci        return -1;
74fb299fa2Sopenharmony_ci    }
75fb299fa2Sopenharmony_ci    size_t offset = std::char_traits<char>::length(PKGDIFF_MAGIC);
76fb299fa2Sopenharmony_ci    int32_t numChunks = ImagePatch::ReadLE<int32_t>(param.patch + offset);
77fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
78fb299fa2Sopenharmony_ci
79fb299fa2Sopenharmony_ci    std::vector<uint8_t> empty;
80fb299fa2Sopenharmony_ci    for (int i = 0; i < numChunks; ++i) {
81fb299fa2Sopenharmony_ci        // each chunk's header record starts with 4 bytes.
82fb299fa2Sopenharmony_ci        if ((offset + sizeof(int32_t)) > param.patchSize) {
83fb299fa2Sopenharmony_ci            PATCH_LOGE("Failed to read chunk record ");
84fb299fa2Sopenharmony_ci            return -1;
85fb299fa2Sopenharmony_ci        }
86fb299fa2Sopenharmony_ci        int32_t type = ImagePatch::ReadLE<int32_t>(param.patch + offset);
87fb299fa2Sopenharmony_ci        PATCH_DEBUG("ApplyImagePatch numChunks[%d] type %d offset %d", i, type, offset);
88fb299fa2Sopenharmony_ci        offset += sizeof(int32_t);
89fb299fa2Sopenharmony_ci        std::unique_ptr<ImagePatch> imagePatch = nullptr;
90fb299fa2Sopenharmony_ci        switch (type) {
91fb299fa2Sopenharmony_ci            case BLOCK_NORMAL:
92fb299fa2Sopenharmony_ci                imagePatch = std::make_unique<NormalImagePatch>(writer);
93fb299fa2Sopenharmony_ci                break;
94fb299fa2Sopenharmony_ci            case BLOCK_RAW:
95fb299fa2Sopenharmony_ci                imagePatch = std::make_unique<RowImagePatch>(writer);
96fb299fa2Sopenharmony_ci                break;
97fb299fa2Sopenharmony_ci            case BLOCK_DEFLATE:
98fb299fa2Sopenharmony_ci                imagePatch = std::make_unique<ZipImagePatch>(writer, ((i == 1) ? bonusData : empty));
99fb299fa2Sopenharmony_ci                break;
100fb299fa2Sopenharmony_ci            case BLOCK_LZ4:
101fb299fa2Sopenharmony_ci                imagePatch = std::make_unique<Lz4ImagePatch>(writer, ((i == 1) ? bonusData : empty));
102fb299fa2Sopenharmony_ci                break;
103fb299fa2Sopenharmony_ci            default:
104fb299fa2Sopenharmony_ci                break;
105fb299fa2Sopenharmony_ci        }
106fb299fa2Sopenharmony_ci        if (imagePatch == nullptr) {
107fb299fa2Sopenharmony_ci            PATCH_LOGE("Failed to  creareimg patch ");
108fb299fa2Sopenharmony_ci            return -1;
109fb299fa2Sopenharmony_ci        }
110fb299fa2Sopenharmony_ci        int32_t ret = imagePatch->ApplyImagePatch(param, offset);
111fb299fa2Sopenharmony_ci        if (ret != 0) {
112fb299fa2Sopenharmony_ci            PATCH_LOGE("Apply image patch fail ");
113fb299fa2Sopenharmony_ci            return -1;
114fb299fa2Sopenharmony_ci        }
115fb299fa2Sopenharmony_ci    }
116fb299fa2Sopenharmony_ci    return 0;
117fb299fa2Sopenharmony_ci}
118fb299fa2Sopenharmony_ci
119fb299fa2Sopenharmony_ciint32_t UpdateApplyPatch::ApplyBlockPatch(const PatchBuffer &patchInfo,
120fb299fa2Sopenharmony_ci    const BlockBuffer &oldInfo, std::vector<uint8_t> &newData)
121fb299fa2Sopenharmony_ci{
122fb299fa2Sopenharmony_ci    std::unique_ptr<BlocksBufferPatch> patch = std::make_unique<BlocksBufferPatch>(patchInfo, oldInfo, newData);
123fb299fa2Sopenharmony_ci    if (patch == nullptr) {
124fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to  creare patch ");
125fb299fa2Sopenharmony_ci        return -1;
126fb299fa2Sopenharmony_ci    }
127fb299fa2Sopenharmony_ci    return patch->ApplyPatch();
128fb299fa2Sopenharmony_ci}
129fb299fa2Sopenharmony_ci
130fb299fa2Sopenharmony_ciint32_t UpdateApplyPatch::ApplyBlockPatch(const PatchBuffer &patchInfo,
131fb299fa2Sopenharmony_ci    const BlockBuffer &oldInfo, UpdatePatchWriterPtr writer)
132fb299fa2Sopenharmony_ci{
133fb299fa2Sopenharmony_ci    PkgManager* pkgManager = Hpackage::PkgManager::CreatePackageInstance();
134fb299fa2Sopenharmony_ci    if (pkgManager == nullptr) {
135fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to get pkg manager");
136fb299fa2Sopenharmony_ci        return -1;
137fb299fa2Sopenharmony_ci    }
138fb299fa2Sopenharmony_ci
139fb299fa2Sopenharmony_ci    Hpackage::PkgManager::StreamPtr stream = nullptr;
140fb299fa2Sopenharmony_ci    int32_t ret = pkgManager->CreatePkgStream(stream, "", {oldInfo.buffer, oldInfo.length});
141fb299fa2Sopenharmony_ci    if (stream == nullptr || ret != PKG_SUCCESS) {
142fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to create stream");
143fb299fa2Sopenharmony_ci        pkgManager->ClosePkgStream(stream);
144fb299fa2Sopenharmony_ci        Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
145fb299fa2Sopenharmony_ci        return -1;
146fb299fa2Sopenharmony_ci    }
147fb299fa2Sopenharmony_ci
148fb299fa2Sopenharmony_ci    std::unique_ptr<BlocksStreamPatch> patch = std::make_unique<BlocksStreamPatch>(patchInfo, stream, writer);
149fb299fa2Sopenharmony_ci    if (patch == nullptr) {
150fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to  creare patch ");
151fb299fa2Sopenharmony_ci        pkgManager->ClosePkgStream(stream);
152fb299fa2Sopenharmony_ci        Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
153fb299fa2Sopenharmony_ci        return -1;
154fb299fa2Sopenharmony_ci    }
155fb299fa2Sopenharmony_ci    ret = patch->ApplyPatch();
156fb299fa2Sopenharmony_ci    pkgManager->ClosePkgStream(stream);
157fb299fa2Sopenharmony_ci    Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
158fb299fa2Sopenharmony_ci    return ret;
159fb299fa2Sopenharmony_ci}
160fb299fa2Sopenharmony_ci
161fb299fa2Sopenharmony_ciint32_t UpdateApplyPatch::ApplyBlockPatch(const PatchBuffer &patchInfo,
162fb299fa2Sopenharmony_ci    const BlockBuffer &oldInfo, ImageProcessor writer, const std::string& expected)
163fb299fa2Sopenharmony_ci{
164fb299fa2Sopenharmony_ci    if (writer == nullptr) {
165fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyBlockPatch : processor is null");
166fb299fa2Sopenharmony_ci        return -1;
167fb299fa2Sopenharmony_ci    }
168fb299fa2Sopenharmony_ci    std::unique_ptr<ImagePatchWriter> patchWriter = std::make_unique<ImagePatchWriter>(writer, expected, "");
169fb299fa2Sopenharmony_ci    if (patchWriter == nullptr) {
170fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyBlockPatch : Failed to create patch writer");
171fb299fa2Sopenharmony_ci        return -1;
172fb299fa2Sopenharmony_ci    }
173fb299fa2Sopenharmony_ci    int32_t ret = patchWriter->Init();
174fb299fa2Sopenharmony_ci    if (ret != 0) {
175fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyBlockPatch : Failed to init patch writer");
176fb299fa2Sopenharmony_ci        return -1;
177fb299fa2Sopenharmony_ci    }
178fb299fa2Sopenharmony_ci
179fb299fa2Sopenharmony_ci    PkgManager* pkgManager = Hpackage::PkgManager::CreatePackageInstance();
180fb299fa2Sopenharmony_ci    if (pkgManager == nullptr) {
181fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyBlockPatch ::Failed to get pkg manager");
182fb299fa2Sopenharmony_ci        return -1;
183fb299fa2Sopenharmony_ci    }
184fb299fa2Sopenharmony_ci
185fb299fa2Sopenharmony_ci    Hpackage::PkgManager::StreamPtr stream = nullptr;
186fb299fa2Sopenharmony_ci    ret = pkgManager->CreatePkgStream(stream, "", {oldInfo.buffer, oldInfo.length});
187fb299fa2Sopenharmony_ci    if (stream == nullptr) {
188fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to create stream");
189fb299fa2Sopenharmony_ci        pkgManager->ClosePkgStream(stream);
190fb299fa2Sopenharmony_ci        Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
191fb299fa2Sopenharmony_ci        return -1;
192fb299fa2Sopenharmony_ci    }
193fb299fa2Sopenharmony_ci
194fb299fa2Sopenharmony_ci    std::unique_ptr<BlocksStreamPatch> patch = std::make_unique<BlocksStreamPatch>(patchInfo,
195fb299fa2Sopenharmony_ci        stream, patchWriter.get());
196fb299fa2Sopenharmony_ci    if (patch == nullptr) {
197fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to  creare patch ");
198fb299fa2Sopenharmony_ci        pkgManager->ClosePkgStream(stream);
199fb299fa2Sopenharmony_ci        Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
200fb299fa2Sopenharmony_ci        return -1;
201fb299fa2Sopenharmony_ci    }
202fb299fa2Sopenharmony_ci    ret = patch->ApplyPatch();
203fb299fa2Sopenharmony_ci    pkgManager->ClosePkgStream(stream);
204fb299fa2Sopenharmony_ci    Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
205fb299fa2Sopenharmony_ci    if (ret != 0) {
206fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to applay patch ");
207fb299fa2Sopenharmony_ci        return -1;
208fb299fa2Sopenharmony_ci    }
209fb299fa2Sopenharmony_ci    return patchWriter->Finish();
210fb299fa2Sopenharmony_ci}
211fb299fa2Sopenharmony_ci
212fb299fa2Sopenharmony_ciint32_t UpdateApplyPatch::ApplyBlockPatch(const PatchBuffer &patchInfo,
213fb299fa2Sopenharmony_ci    Hpackage::PkgManager::StreamPtr stream, UpdatePatchWriterPtr writer)
214fb299fa2Sopenharmony_ci{
215fb299fa2Sopenharmony_ci    std::unique_ptr<BlocksStreamPatch> patch = std::make_unique<BlocksStreamPatch>(patchInfo, stream, writer);
216fb299fa2Sopenharmony_ci    if (patch == nullptr) {
217fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to  creare patch ");
218fb299fa2Sopenharmony_ci        return -1;
219fb299fa2Sopenharmony_ci    }
220fb299fa2Sopenharmony_ci    return patch->ApplyPatch();
221fb299fa2Sopenharmony_ci}
222fb299fa2Sopenharmony_ci
223fb299fa2Sopenharmony_ciint32_t UpdateApplyPatch::ApplyPatch(const std::string &patchName,
224fb299fa2Sopenharmony_ci    const std::string &oldName, const std::string &newName)
225fb299fa2Sopenharmony_ci{
226fb299fa2Sopenharmony_ci    PATCH_DEBUG("UpdatePatch::ApplyPatch : %s ", patchName.c_str());
227fb299fa2Sopenharmony_ci    std::vector<uint8_t> empty;
228fb299fa2Sopenharmony_ci    MemMapInfo patchData {};
229fb299fa2Sopenharmony_ci    MemMapInfo oldData {};
230fb299fa2Sopenharmony_ci    if (PatchMapFile(patchName, patchData) != 0) {
231fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyPatch : Failed to read patch file");
232fb299fa2Sopenharmony_ci        return -1;
233fb299fa2Sopenharmony_ci    }
234fb299fa2Sopenharmony_ci    if (PatchMapFile(oldName, oldData) != 0) {
235fb299fa2Sopenharmony_ci        PATCH_LOGE("ApplyPatch : Failed to read old file");
236fb299fa2Sopenharmony_ci        return -1;
237fb299fa2Sopenharmony_ci    }
238fb299fa2Sopenharmony_ci    PATCH_LOGI("UpdatePatch::ApplyPatch patchData %zu oldData %zu ", patchData.length, oldData.length);
239fb299fa2Sopenharmony_ci    std::unique_ptr<FilePatchWriter> writer = std::make_unique<FilePatchWriter>(newName);
240fb299fa2Sopenharmony_ci    if (writer == nullptr) {
241fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to create writer");
242fb299fa2Sopenharmony_ci        return -1;
243fb299fa2Sopenharmony_ci    }
244fb299fa2Sopenharmony_ci    writer->Init();
245fb299fa2Sopenharmony_ci
246fb299fa2Sopenharmony_ci    // check if image patch
247fb299fa2Sopenharmony_ci    if (patchData.length < std::char_traits<char>::length(PKGDIFF_MAGIC)) {
248fb299fa2Sopenharmony_ci        PATCH_LOGE("length error");
249fb299fa2Sopenharmony_ci        return -1;
250fb299fa2Sopenharmony_ci    }
251fb299fa2Sopenharmony_ci    if (memcmp(patchData.memory, PKGDIFF_MAGIC, std::char_traits<char>::length(PKGDIFF_MAGIC)) == 0) {
252fb299fa2Sopenharmony_ci        PatchParam param {};
253fb299fa2Sopenharmony_ci        param.patch = patchData.memory;
254fb299fa2Sopenharmony_ci        param.patchSize = patchData.length;
255fb299fa2Sopenharmony_ci        param.oldBuff = oldData.memory;
256fb299fa2Sopenharmony_ci        param.oldSize = oldData.length;
257fb299fa2Sopenharmony_ci        if (UpdatePatch::UpdateApplyPatch::ApplyImagePatch(param, writer.get(), empty) != 0) {
258fb299fa2Sopenharmony_ci            PATCH_LOGE("Failed to apply image patch file");
259fb299fa2Sopenharmony_ci            return -1;
260fb299fa2Sopenharmony_ci        }
261fb299fa2Sopenharmony_ci    } else if (memcmp(patchData.memory, BSDIFF_MAGIC, std::char_traits<char>::length(BSDIFF_MAGIC)) == 0) { // bsdiff
262fb299fa2Sopenharmony_ci        PatchBuffer patchInfo = {patchData.memory, 0, patchData.length};
263fb299fa2Sopenharmony_ci        BlockBuffer oldInfo = {oldData.memory, oldData.length};
264fb299fa2Sopenharmony_ci        if (ApplyBlockPatch(patchInfo, oldInfo, writer.get()) != 0) {
265fb299fa2Sopenharmony_ci            PATCH_LOGE("Failed to apply block patch");
266fb299fa2Sopenharmony_ci            return -1;
267fb299fa2Sopenharmony_ci        }
268fb299fa2Sopenharmony_ci    } else {
269fb299fa2Sopenharmony_ci        PATCH_LOGE("Invalid patch file");
270fb299fa2Sopenharmony_ci        return -1;
271fb299fa2Sopenharmony_ci    }
272fb299fa2Sopenharmony_ci    writer->Finish();
273fb299fa2Sopenharmony_ci    return 0;
274fb299fa2Sopenharmony_ci}
275fb299fa2Sopenharmony_ci
276fb299fa2Sopenharmony_ciint32_t ImagePatchWriter::Init()
277fb299fa2Sopenharmony_ci{
278fb299fa2Sopenharmony_ci    if (init_) {
279fb299fa2Sopenharmony_ci        PATCH_LOGE("Has beed init");
280fb299fa2Sopenharmony_ci        return -1;
281fb299fa2Sopenharmony_ci    }
282fb299fa2Sopenharmony_ci    if (writer_ == nullptr) {
283fb299fa2Sopenharmony_ci        PATCH_LOGE("Writer is null");
284fb299fa2Sopenharmony_ci        return -1;
285fb299fa2Sopenharmony_ci    }
286fb299fa2Sopenharmony_ci    SHA256_Init(&sha256Ctx_);
287fb299fa2Sopenharmony_ci    init_ = true;
288fb299fa2Sopenharmony_ci    return 0;
289fb299fa2Sopenharmony_ci}
290fb299fa2Sopenharmony_ci
291fb299fa2Sopenharmony_ciint32_t ImagePatchWriter::Write(size_t start, const BlockBuffer &buffer, size_t len)
292fb299fa2Sopenharmony_ci{
293fb299fa2Sopenharmony_ci    if (!init_) {
294fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check init");
295fb299fa2Sopenharmony_ci        return -1;
296fb299fa2Sopenharmony_ci    }
297fb299fa2Sopenharmony_ci    if (len == 0) {
298fb299fa2Sopenharmony_ci        return 0;
299fb299fa2Sopenharmony_ci    }
300fb299fa2Sopenharmony_ci    SHA256_Update(&sha256Ctx_, buffer.buffer, len);
301fb299fa2Sopenharmony_ci    return writer_(start, buffer, len);
302fb299fa2Sopenharmony_ci}
303fb299fa2Sopenharmony_ci
304fb299fa2Sopenharmony_ciint32_t ImagePatchWriter::Finish()
305fb299fa2Sopenharmony_ci{
306fb299fa2Sopenharmony_ci    if (!init_) {
307fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check init");
308fb299fa2Sopenharmony_ci        return -1;
309fb299fa2Sopenharmony_ci    }
310fb299fa2Sopenharmony_ci    std::vector<uint8_t> digest(SHA256_DIGEST_LENGTH);
311fb299fa2Sopenharmony_ci    SHA256_Final(digest.data(), &sha256Ctx_);
312fb299fa2Sopenharmony_ci    BlockBuffer data = {  digest.data(), digest.size() };
313fb299fa2Sopenharmony_ci    std::string hexDigest = ConvertSha256Hex(data);
314fb299fa2Sopenharmony_ci    init_ = false;
315fb299fa2Sopenharmony_ci    int32_t ret = hexDigest.compare(expected_);
316fb299fa2Sopenharmony_ci    if (ret != 0) {
317fb299fa2Sopenharmony_ci        PATCH_LOGE("VerifySha256 SHA256 : %s expected SHA256 : %s", hexDigest.c_str(), expected_.c_str());
318fb299fa2Sopenharmony_ci        return ret;
319fb299fa2Sopenharmony_ci    }
320fb299fa2Sopenharmony_ci    return 0;
321fb299fa2Sopenharmony_ci}
322fb299fa2Sopenharmony_ci
323fb299fa2Sopenharmony_ciint32_t FilePatchWriter::Init()
324fb299fa2Sopenharmony_ci{
325fb299fa2Sopenharmony_ci    if (init_) {
326fb299fa2Sopenharmony_ci        PATCH_LOGE("Has beed init");
327fb299fa2Sopenharmony_ci        return -1;
328fb299fa2Sopenharmony_ci    }
329fb299fa2Sopenharmony_ci    if (!stream_.is_open()) {
330fb299fa2Sopenharmony_ci        stream_.open(newFileName_, std::ios::out | std::ios::binary);
331fb299fa2Sopenharmony_ci        if (stream_.fail()) {
332fb299fa2Sopenharmony_ci            PATCH_LOGE("Failed to open %s", newFileName_.c_str());
333fb299fa2Sopenharmony_ci            return -1;
334fb299fa2Sopenharmony_ci        }
335fb299fa2Sopenharmony_ci    }
336fb299fa2Sopenharmony_ci    init_ = true;
337fb299fa2Sopenharmony_ci    return 0;
338fb299fa2Sopenharmony_ci}
339fb299fa2Sopenharmony_ci
340fb299fa2Sopenharmony_ciint32_t FilePatchWriter::Write(size_t start, const BlockBuffer &buffer, size_t len)
341fb299fa2Sopenharmony_ci{
342fb299fa2Sopenharmony_ci    if (!init_) {
343fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check init");
344fb299fa2Sopenharmony_ci        return -1;
345fb299fa2Sopenharmony_ci    }
346fb299fa2Sopenharmony_ci    if (len == 0) {
347fb299fa2Sopenharmony_ci        return 0;
348fb299fa2Sopenharmony_ci    }
349fb299fa2Sopenharmony_ci    if (!stream_.is_open()) {
350fb299fa2Sopenharmony_ci        stream_.open(newFileName_, std::ios::out | std::ios::binary);
351fb299fa2Sopenharmony_ci        if (stream_.fail()) {
352fb299fa2Sopenharmony_ci            PATCH_LOGE("Failed to open %s", newFileName_.c_str());
353fb299fa2Sopenharmony_ci            return -1;
354fb299fa2Sopenharmony_ci        }
355fb299fa2Sopenharmony_ci    }
356fb299fa2Sopenharmony_ci    stream_.write(reinterpret_cast<const char*>(buffer.buffer), len);
357fb299fa2Sopenharmony_ci    return 0;
358fb299fa2Sopenharmony_ci}
359fb299fa2Sopenharmony_ci
360fb299fa2Sopenharmony_ciint32_t FilePatchWriter::Finish()
361fb299fa2Sopenharmony_ci{
362fb299fa2Sopenharmony_ci    if (!init_) {
363fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check init");
364fb299fa2Sopenharmony_ci        return -1;
365fb299fa2Sopenharmony_ci    }
366fb299fa2Sopenharmony_ci    PATCH_LOGI("FilePatchWriter %zu", static_cast<size_t>(stream_.tellp()));
367fb299fa2Sopenharmony_ci    stream_.close();
368fb299fa2Sopenharmony_ci    init_ = false;
369fb299fa2Sopenharmony_ci    return 0;
370fb299fa2Sopenharmony_ci}
371fb299fa2Sopenharmony_ci} // namespace UpdatePatch