• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2024 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 <fstream>
17 #include <map>
18 #include <cstdio>
19 #include <cstdlib>
20 
21 #include "fs_digest_utils.h"
22 #include "file_utils.h"
23 #include "hash_utils.h"
24 
25 namespace OHOS {
26 namespace SignatureTools {
27 
GetHashAlgsId(const std::string & algMethod)28 int HashUtils::GetHashAlgsId(const std::string& algMethod)
29 {
30     int result = static_cast<int>(HashAlgs::USE_NONE);
31     if (0 == algMethod.compare("SHA-256")) {
32         result = static_cast<int>(HashAlgs::USE_SHA256);
33     }
34     if (0 == algMethod.compare("SHA-384")) {
35         result = static_cast<int>(HashAlgs::USE_SHA384);
36     }
37     if (0 == algMethod.compare("SHA-512")) {
38         result = static_cast<int>(HashAlgs::USE_SHA512);
39     }
40     return result;
41 }
42 
GetHashAlgName(int algId)43 std::string HashUtils::GetHashAlgName(int algId)
44 {
45     if (static_cast<int>(HashAlgs::USE_SHA256) == algId) {
46         return "SHA-256";
47     }
48     if (static_cast<int>(HashAlgs::USE_SHA384) == algId) {
49         return "SHA-384";
50     }
51     if (static_cast<int>(HashAlgs::USE_SHA512) == algId) {
52         return "SHA-512";
53     }
54     return "";
55 }
56 
GetFileDigest(const std::string & inputFile,const std::string & algName)57 std::vector<int8_t> HashUtils::GetFileDigest(const std::string& inputFile, const std::string& algName)
58 {
59     std::vector<int8_t> result;
60 
61     std::ifstream input(inputFile, std::ios::binary);
62     if (0 != input.rdstate()) {
63         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "failed to get input stream object!");
64         return std::vector<int8_t>();
65     }
66 
67     char buffer[HASH_LEN] = { 0 };
68     int num = 0;
69     std::map<int, std::vector<int8_t>> hashMap;
70 
71     while (!input.eof()) {
72         input.read(buffer, HASH_LEN);
73 
74         if (input.fail() && !input.eof()) {
75             PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "error occurred while reading data.");
76             return std::vector<int8_t>();
77         }
78 
79         std::streamsize readLen = input.gcount();
80         std::string str;
81         for (int i = 0; i < readLen; ++i) {
82             str.push_back(buffer[i]);
83         }
84 
85         std::vector<int8_t> dig = GetByteDigest(str, readLen, algName);
86         hashMap.emplace(num, dig);
87         ++num;
88     }
89 
90     if (hashMap.empty()) {
91         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "hashMap is empty.");
92         return std::vector<int8_t>();
93     }
94 
95     DigestUtils fileDigestUtils(HASH_SHA256);
96     for (const auto& hashMapItem : hashMap) {
97         std::string str(hashMapItem.second.begin(), hashMapItem.second.end());
98         fileDigestUtils.AddData(str);
99     }
100     std::string digest = fileDigestUtils.Result(DigestUtils::Type::BINARY);
101     for (std::string::size_type i = 0; i < digest.size(); i++) {
102         result.push_back(digest[i]);
103     }
104     return result;
105 }
106 
GetDigestFromBytes(const std::vector<int8_t> & fileBytes,int64_t length,const std::string & algName)107 std::vector<int8_t> HashUtils::GetDigestFromBytes(const std::vector<int8_t>& fileBytes, int64_t length,
108                                                   const std::string& algName)
109 {
110     if (fileBytes.empty() || length <= 0) {
111         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "file bytes is empty.");
112         return std::vector<int8_t>();
113     }
114     std::map<int, std::vector<int8_t>> hashMap;
115     int64_t readLength = 0;
116     int64_t num = 0;
117     while (readLength < length) {
118         int64_t blockLength = length - readLength > HASH_LEN ? HASH_LEN : (length - readLength);
119         std::string readStr(fileBytes.begin() + readLength, fileBytes.begin() + readLength + blockLength);
120         std::vector<int8_t> dig = GetByteDigest(readStr, readStr.size(), algName);
121         hashMap.emplace(num, dig);
122         ++num;
123         readLength += readStr.size();
124     }
125     if (hashMap.empty()) {
126         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "hashMap is empty.");
127         return std::vector<int8_t>();
128     }
129     DigestUtils digestUtils(HASH_SHA256);
130     for (const auto& item : hashMap) {
131         std::string str(item.second.begin(), item.second.end());
132         digestUtils.AddData(str);
133     }
134     std::string digest = digestUtils.Result(DigestUtils::Type::BINARY);
135     std::vector<int8_t> result;
136     for (std::string::size_type i = 0; i < digest.size(); i++) {
137         result.push_back(digest[i]);
138     }
139     return result;
140 }
141 
GetByteDigest(const std::string & str,int count,const std::string & algMethod)142 std::vector<int8_t> HashUtils::GetByteDigest(const std::string& str, int count, const std::string& algMethod)
143 {
144     std::vector<int8_t> result;
145     DigestUtils digestUtils(HASH_SHA256);
146     digestUtils.AddData(str);
147     std::string digest = digestUtils.Result(DigestUtils::Type::BINARY);
148     for (std::string::size_type i = 0; i < digest.size(); i++) {
149         result.push_back(digest[i]);
150     }
151     return result;
152 }
153 
154 } // namespace SignatureTools
155 } // namespace OHOS