154aa6d63Sopenharmony_ci/* 254aa6d63Sopenharmony_ci * Copyright (c) 2024-2024 Huawei Device Co., Ltd. 354aa6d63Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 454aa6d63Sopenharmony_ci * you may not use this file except in compliance with the License. 554aa6d63Sopenharmony_ci * You may obtain a copy of the License at 654aa6d63Sopenharmony_ci * 754aa6d63Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 854aa6d63Sopenharmony_ci * 954aa6d63Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1054aa6d63Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1154aa6d63Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1254aa6d63Sopenharmony_ci * See the License for the specific language governing permissions and 1354aa6d63Sopenharmony_ci * limitations under the License. 1454aa6d63Sopenharmony_ci */ 1554aa6d63Sopenharmony_ci 1654aa6d63Sopenharmony_ci#include <fstream> 1754aa6d63Sopenharmony_ci#include <map> 1854aa6d63Sopenharmony_ci#include <cstdio> 1954aa6d63Sopenharmony_ci#include <cstdlib> 2054aa6d63Sopenharmony_ci 2154aa6d63Sopenharmony_ci#include "fs_digest_utils.h" 2254aa6d63Sopenharmony_ci#include "file_utils.h" 2354aa6d63Sopenharmony_ci#include "hash_utils.h" 2454aa6d63Sopenharmony_ci 2554aa6d63Sopenharmony_cinamespace OHOS { 2654aa6d63Sopenharmony_cinamespace SignatureTools { 2754aa6d63Sopenharmony_ci 2854aa6d63Sopenharmony_ciint HashUtils::GetHashAlgsId(const std::string& algMethod) 2954aa6d63Sopenharmony_ci{ 3054aa6d63Sopenharmony_ci int result = static_cast<int>(HashAlgs::USE_NONE); 3154aa6d63Sopenharmony_ci if (0 == algMethod.compare("SHA-256")) { 3254aa6d63Sopenharmony_ci result = static_cast<int>(HashAlgs::USE_SHA256); 3354aa6d63Sopenharmony_ci } 3454aa6d63Sopenharmony_ci if (0 == algMethod.compare("SHA-384")) { 3554aa6d63Sopenharmony_ci result = static_cast<int>(HashAlgs::USE_SHA384); 3654aa6d63Sopenharmony_ci } 3754aa6d63Sopenharmony_ci if (0 == algMethod.compare("SHA-512")) { 3854aa6d63Sopenharmony_ci result = static_cast<int>(HashAlgs::USE_SHA512); 3954aa6d63Sopenharmony_ci } 4054aa6d63Sopenharmony_ci return result; 4154aa6d63Sopenharmony_ci} 4254aa6d63Sopenharmony_ci 4354aa6d63Sopenharmony_cistd::string HashUtils::GetHashAlgName(int algId) 4454aa6d63Sopenharmony_ci{ 4554aa6d63Sopenharmony_ci if (static_cast<int>(HashAlgs::USE_SHA256) == algId) { 4654aa6d63Sopenharmony_ci return "SHA-256"; 4754aa6d63Sopenharmony_ci } 4854aa6d63Sopenharmony_ci if (static_cast<int>(HashAlgs::USE_SHA384) == algId) { 4954aa6d63Sopenharmony_ci return "SHA-384"; 5054aa6d63Sopenharmony_ci } 5154aa6d63Sopenharmony_ci if (static_cast<int>(HashAlgs::USE_SHA512) == algId) { 5254aa6d63Sopenharmony_ci return "SHA-512"; 5354aa6d63Sopenharmony_ci } 5454aa6d63Sopenharmony_ci return ""; 5554aa6d63Sopenharmony_ci} 5654aa6d63Sopenharmony_ci 5754aa6d63Sopenharmony_cistd::vector<int8_t> HashUtils::GetFileDigest(const std::string& inputFile, const std::string& algName) 5854aa6d63Sopenharmony_ci{ 5954aa6d63Sopenharmony_ci std::vector<int8_t> result; 6054aa6d63Sopenharmony_ci 6154aa6d63Sopenharmony_ci std::ifstream input(inputFile, std::ios::binary); 6254aa6d63Sopenharmony_ci if (0 != input.rdstate()) { 6354aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "failed to get input stream object!"); 6454aa6d63Sopenharmony_ci return std::vector<int8_t>(); 6554aa6d63Sopenharmony_ci } 6654aa6d63Sopenharmony_ci 6754aa6d63Sopenharmony_ci char buffer[HASH_LEN] = { 0 }; 6854aa6d63Sopenharmony_ci int num = 0; 6954aa6d63Sopenharmony_ci std::map<int, std::vector<int8_t>> hashMap; 7054aa6d63Sopenharmony_ci 7154aa6d63Sopenharmony_ci while (!input.eof()) { 7254aa6d63Sopenharmony_ci input.read(buffer, HASH_LEN); 7354aa6d63Sopenharmony_ci 7454aa6d63Sopenharmony_ci if (input.fail() && !input.eof()) { 7554aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "error occurred while reading data."); 7654aa6d63Sopenharmony_ci return std::vector<int8_t>(); 7754aa6d63Sopenharmony_ci } 7854aa6d63Sopenharmony_ci 7954aa6d63Sopenharmony_ci std::streamsize readLen = input.gcount(); 8054aa6d63Sopenharmony_ci std::string str; 8154aa6d63Sopenharmony_ci for (int i = 0; i < readLen; ++i) { 8254aa6d63Sopenharmony_ci str.push_back(buffer[i]); 8354aa6d63Sopenharmony_ci } 8454aa6d63Sopenharmony_ci 8554aa6d63Sopenharmony_ci std::vector<int8_t> dig = GetByteDigest(str, readLen, algName); 8654aa6d63Sopenharmony_ci hashMap.emplace(num, dig); 8754aa6d63Sopenharmony_ci ++num; 8854aa6d63Sopenharmony_ci } 8954aa6d63Sopenharmony_ci 9054aa6d63Sopenharmony_ci if (hashMap.empty()) { 9154aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "hashMap is empty."); 9254aa6d63Sopenharmony_ci return std::vector<int8_t>(); 9354aa6d63Sopenharmony_ci } 9454aa6d63Sopenharmony_ci 9554aa6d63Sopenharmony_ci DigestUtils fileDigestUtils(HASH_SHA256); 9654aa6d63Sopenharmony_ci for (const auto& hashMapItem : hashMap) { 9754aa6d63Sopenharmony_ci std::string str(hashMapItem.second.begin(), hashMapItem.second.end()); 9854aa6d63Sopenharmony_ci fileDigestUtils.AddData(str); 9954aa6d63Sopenharmony_ci } 10054aa6d63Sopenharmony_ci std::string digest = fileDigestUtils.Result(DigestUtils::Type::BINARY); 10154aa6d63Sopenharmony_ci for (std::string::size_type i = 0; i < digest.size(); i++) { 10254aa6d63Sopenharmony_ci result.push_back(digest[i]); 10354aa6d63Sopenharmony_ci } 10454aa6d63Sopenharmony_ci return result; 10554aa6d63Sopenharmony_ci} 10654aa6d63Sopenharmony_ci 10754aa6d63Sopenharmony_cistd::vector<int8_t> HashUtils::GetDigestFromBytes(const std::vector<int8_t>& fileBytes, int64_t length, 10854aa6d63Sopenharmony_ci const std::string& algName) 10954aa6d63Sopenharmony_ci{ 11054aa6d63Sopenharmony_ci if (fileBytes.empty() || length <= 0) { 11154aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "file bytes is empty."); 11254aa6d63Sopenharmony_ci return std::vector<int8_t>(); 11354aa6d63Sopenharmony_ci } 11454aa6d63Sopenharmony_ci std::map<int, std::vector<int8_t>> hashMap; 11554aa6d63Sopenharmony_ci int64_t readLength = 0; 11654aa6d63Sopenharmony_ci int64_t num = 0; 11754aa6d63Sopenharmony_ci while (readLength < length) { 11854aa6d63Sopenharmony_ci int64_t blockLength = length - readLength > HASH_LEN ? HASH_LEN : (length - readLength); 11954aa6d63Sopenharmony_ci std::string readStr(fileBytes.begin() + readLength, fileBytes.begin() + readLength + blockLength); 12054aa6d63Sopenharmony_ci std::vector<int8_t> dig = GetByteDigest(readStr, readStr.size(), algName); 12154aa6d63Sopenharmony_ci hashMap.emplace(num, dig); 12254aa6d63Sopenharmony_ci ++num; 12354aa6d63Sopenharmony_ci readLength += readStr.size(); 12454aa6d63Sopenharmony_ci } 12554aa6d63Sopenharmony_ci if (hashMap.empty()) { 12654aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "hashMap is empty."); 12754aa6d63Sopenharmony_ci return std::vector<int8_t>(); 12854aa6d63Sopenharmony_ci } 12954aa6d63Sopenharmony_ci DigestUtils digestUtils(HASH_SHA256); 13054aa6d63Sopenharmony_ci for (const auto& item : hashMap) { 13154aa6d63Sopenharmony_ci std::string str(item.second.begin(), item.second.end()); 13254aa6d63Sopenharmony_ci digestUtils.AddData(str); 13354aa6d63Sopenharmony_ci } 13454aa6d63Sopenharmony_ci std::string digest = digestUtils.Result(DigestUtils::Type::BINARY); 13554aa6d63Sopenharmony_ci std::vector<int8_t> result; 13654aa6d63Sopenharmony_ci for (std::string::size_type i = 0; i < digest.size(); i++) { 13754aa6d63Sopenharmony_ci result.push_back(digest[i]); 13854aa6d63Sopenharmony_ci } 13954aa6d63Sopenharmony_ci return result; 14054aa6d63Sopenharmony_ci} 14154aa6d63Sopenharmony_ci 14254aa6d63Sopenharmony_cistd::vector<int8_t> HashUtils::GetByteDigest(const std::string& str, int count, const std::string& algMethod) 14354aa6d63Sopenharmony_ci{ 14454aa6d63Sopenharmony_ci std::vector<int8_t> result; 14554aa6d63Sopenharmony_ci DigestUtils digestUtils(HASH_SHA256); 14654aa6d63Sopenharmony_ci digestUtils.AddData(str); 14754aa6d63Sopenharmony_ci std::string digest = digestUtils.Result(DigestUtils::Type::BINARY); 14854aa6d63Sopenharmony_ci for (std::string::size_type i = 0; i < digest.size(); i++) { 14954aa6d63Sopenharmony_ci result.push_back(digest[i]); 15054aa6d63Sopenharmony_ci } 15154aa6d63Sopenharmony_ci return result; 15254aa6d63Sopenharmony_ci} 15354aa6d63Sopenharmony_ci 15454aa6d63Sopenharmony_ci} // namespace SignatureTools 15554aa6d63Sopenharmony_ci} // namespace OHOS