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
16 #include "diffpatch.h"
17 #ifndef __WIN32
18 #include <climits>
19 #include <sys/mman.h>
20 #endif
21 #include <cstdlib>
22 #include <fcntl.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <vector>
26 #include "openssl/sha.h"
27
28 namespace UpdatePatch {
WriteDataToFile(const std::string & fileName,const std::vector<uint8_t> & data,size_t dataSize)29 int32_t WriteDataToFile(const std::string &fileName, const std::vector<uint8_t> &data, size_t dataSize)
30 {
31 std::ofstream patchFile(fileName, std::ios::out | std::ios::binary);
32 if (!patchFile) {
33 PATCH_LOGE("Failed to open %s", fileName.c_str());
34 return -1;
35 }
36 patchFile.write(reinterpret_cast<const char*>(data.data()), dataSize);
37 patchFile.close();
38 return PATCH_SUCCESS;
39 }
40
PatchMapFile(const std::string & fileName,MemMapInfo & info)41 int32_t PatchMapFile(const std::string &fileName, MemMapInfo &info)
42 {
43 char realPath[PATH_MAX] = { 0 };
44 #ifdef _WIN32
45 if (_fullpath(realPath, fileName.c_str(), PATH_MAX) == nullptr) {
46 #else
47 if (realpath(fileName.c_str(), realPath) == nullptr) {
48 #endif
49 PATCH_LOGE("Failed to get realpath %s", fileName.c_str());
50 return -1;
51 }
52 info.fd = open(realPath, O_RDONLY);
53 if (info.fd < 0) {
54 PATCH_LOGE("Failed to open file %s", fileName.c_str());
55 return -1;
56 }
57 struct stat st {};
58 int32_t ret = fstat(info.fd, &st);
59 if (ret < 0) {
60 PATCH_LOGE("Failed to fstat");
61 return ret;
62 }
63 if (S_ISBLK(st.st_mode)) {
64 st.st_size = lseek(info.fd, 0, SEEK_END);
65 lseek(info.fd, 0, SEEK_SET);
66 }
67
68 info.memory = static_cast<uint8_t*>(mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, info.fd, 0));
69 if (info.memory == nullptr) {
70 PATCH_LOGE("Failed to memory map");
71 return -1;
72 }
73 info.length = static_cast<size_t>(st.st_size);
74 return PATCH_SUCCESS;
75 }
76
77 std::string GeneraterBufferHash(const BlockBuffer &buffer)
78 {
79 SHA256_CTX sha256Ctx;
80 SHA256_Init(&sha256Ctx);
81 SHA256_Update(&sha256Ctx, buffer.buffer, buffer.length);
82 std::vector<uint8_t> digest(SHA256_DIGEST_LENGTH);
83 SHA256_Final(digest.data(), &sha256Ctx);
84 return ConvertSha256Hex({
85 digest.data(), SHA256_DIGEST_LENGTH
86 });
87 }
88
89 std::string ConvertSha256Hex(const BlockBuffer &buffer)
90 {
91 const std::string hexChars = "0123456789abcdef";
92 std::string haxSha256 = "";
93 unsigned int c;
94 for (size_t i = 0; i < buffer.length; ++i) {
95 auto d = buffer.buffer[i];
96 c = (d >> SHIFT_RIGHT_FOUR_BITS) & 0xf; // last 4 bits
97 haxSha256.push_back(hexChars[c]);
98 haxSha256.push_back(hexChars[d & 0xf]);
99 }
100 return haxSha256;
101 }
102 } // namespace UpdatePatch
103