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#include "digest_common.h" 1654aa6d63Sopenharmony_ci#include "signature_tools_log.h" 1754aa6d63Sopenharmony_ci#include "openssl/err.h" 1854aa6d63Sopenharmony_ci 1954aa6d63Sopenharmony_cinamespace OHOS { 2054aa6d63Sopenharmony_cinamespace SignatureTools { 2154aa6d63Sopenharmony_ciconst int32_t DigestCommon::OPENSSL_ERR_MESSAGE_MAX_LEN = 1024; 2254aa6d63Sopenharmony_ci 2354aa6d63Sopenharmony_ciint32_t DigestCommon::GetDigestAlgorithmOutputSizeBytes(int32_t nId) 2454aa6d63Sopenharmony_ci{ 2554aa6d63Sopenharmony_ci return EVP_MD_size(EVP_get_digestbynid(nId)); 2654aa6d63Sopenharmony_ci} 2754aa6d63Sopenharmony_ci 2854aa6d63Sopenharmony_cibool DigestCommon::CheckDigestParameter(const DigestParameter& digestParameter) 2954aa6d63Sopenharmony_ci{ 3054aa6d63Sopenharmony_ci if (digestParameter.md == nullptr) { 3154aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("md is nullptr"); 3254aa6d63Sopenharmony_ci return false; 3354aa6d63Sopenharmony_ci } 3454aa6d63Sopenharmony_ci if (digestParameter.ctxPtr == nullptr) { 3554aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("ctxPtr is nullptr"); 3654aa6d63Sopenharmony_ci return false; 3754aa6d63Sopenharmony_ci } 3854aa6d63Sopenharmony_ci return true; 3954aa6d63Sopenharmony_ci} 4054aa6d63Sopenharmony_ci 4154aa6d63Sopenharmony_cibool DigestCommon::DigestInit(const DigestParameter& digestParameter) 4254aa6d63Sopenharmony_ci{ 4354aa6d63Sopenharmony_ci if (!CheckDigestParameter(digestParameter)) { 4454aa6d63Sopenharmony_ci return false; 4554aa6d63Sopenharmony_ci } 4654aa6d63Sopenharmony_ci if (EVP_DigestInit(digestParameter.ctxPtr, digestParameter.md) <= 0) { 4754aa6d63Sopenharmony_ci GetOpensslErrorMessage(); 4854aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("EVP_DigestInit failed"); 4954aa6d63Sopenharmony_ci return false; 5054aa6d63Sopenharmony_ci } 5154aa6d63Sopenharmony_ci return true; 5254aa6d63Sopenharmony_ci} 5354aa6d63Sopenharmony_ci 5454aa6d63Sopenharmony_ci/* the caller must ensure that EVP_DigestInit was called before calling this function */ 5554aa6d63Sopenharmony_cibool DigestCommon::DigestUpdate(const DigestParameter& digestParameter, 5654aa6d63Sopenharmony_ci const unsigned char content[], int32_t len) 5754aa6d63Sopenharmony_ci{ 5854aa6d63Sopenharmony_ci if (content == nullptr) { 5954aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("content is nullptr"); 6054aa6d63Sopenharmony_ci return false; 6154aa6d63Sopenharmony_ci } 6254aa6d63Sopenharmony_ci if (!CheckDigestParameter(digestParameter)) { 6354aa6d63Sopenharmony_ci return false; 6454aa6d63Sopenharmony_ci } 6554aa6d63Sopenharmony_ci if (EVP_DigestUpdate(digestParameter.ctxPtr, content, len) <= 0) { 6654aa6d63Sopenharmony_ci GetOpensslErrorMessage(); 6754aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("EVP_DigestUpdate failed"); 6854aa6d63Sopenharmony_ci return false; 6954aa6d63Sopenharmony_ci } 7054aa6d63Sopenharmony_ci return true; 7154aa6d63Sopenharmony_ci} 7254aa6d63Sopenharmony_ci 7354aa6d63Sopenharmony_ciint32_t DigestCommon::GetDigest(const DigestParameter& digestParameter, 7454aa6d63Sopenharmony_ci unsigned char(&out)[EVP_MAX_MD_SIZE]) 7554aa6d63Sopenharmony_ci{ 7654aa6d63Sopenharmony_ci uint32_t outLen = 0; 7754aa6d63Sopenharmony_ci if (!CheckDigestParameter(digestParameter)) { 7854aa6d63Sopenharmony_ci return outLen; 7954aa6d63Sopenharmony_ci } 8054aa6d63Sopenharmony_ci if (EVP_DigestFinal(digestParameter.ctxPtr, out, &outLen) <= 0) { 8154aa6d63Sopenharmony_ci GetOpensslErrorMessage(); 8254aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("EVP_DigestFinal failed"); 8354aa6d63Sopenharmony_ci outLen = 0; 8454aa6d63Sopenharmony_ci } 8554aa6d63Sopenharmony_ci return outLen; 8654aa6d63Sopenharmony_ci} 8754aa6d63Sopenharmony_ci 8854aa6d63Sopenharmony_ciint32_t DigestCommon::GetDigest(const ByteBuffer& chunk, 8954aa6d63Sopenharmony_ci const std::vector<OptionalBlock>& optionalBlocks, 9054aa6d63Sopenharmony_ci const DigestParameter& digestParameter, 9154aa6d63Sopenharmony_ci unsigned char(&out)[EVP_MAX_MD_SIZE]) 9254aa6d63Sopenharmony_ci{ 9354aa6d63Sopenharmony_ci int32_t chunkLen = chunk.Remaining(); 9454aa6d63Sopenharmony_ci uint32_t outLen = 0; 9554aa6d63Sopenharmony_ci if (digestParameter.md == nullptr) { 9654aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("md is nullprt"); 9754aa6d63Sopenharmony_ci return outLen; 9854aa6d63Sopenharmony_ci } 9954aa6d63Sopenharmony_ci if (digestParameter.ctxPtr == nullptr) { 10054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("ctxPtr is nullprt"); 10154aa6d63Sopenharmony_ci return outLen; 10254aa6d63Sopenharmony_ci } 10354aa6d63Sopenharmony_ci if (EVP_DigestInit(digestParameter.ctxPtr, digestParameter.md) <= 0) { 10454aa6d63Sopenharmony_ci GetOpensslErrorMessage(); 10554aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("EVP_DigestInit failed"); 10654aa6d63Sopenharmony_ci return outLen; 10754aa6d63Sopenharmony_ci } 10854aa6d63Sopenharmony_ci if (EVP_DigestUpdate(digestParameter.ctxPtr, chunk.GetBufferPtr(), chunkLen) <= 0) { 10954aa6d63Sopenharmony_ci GetOpensslErrorMessage(); 11054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("EVP_DigestUpdate chunk failed"); 11154aa6d63Sopenharmony_ci return outLen; 11254aa6d63Sopenharmony_ci } 11354aa6d63Sopenharmony_ci for (int32_t i = 0; i < static_cast<int>(optionalBlocks.size()); i++) { 11454aa6d63Sopenharmony_ci chunkLen = optionalBlocks[i].optionalBlockValue.GetCapacity(); 11554aa6d63Sopenharmony_ci if (EVP_DigestUpdate(digestParameter.ctxPtr, optionalBlocks[i].optionalBlockValue.GetBufferPtr(), 11654aa6d63Sopenharmony_ci chunkLen) <= 0) { 11754aa6d63Sopenharmony_ci GetOpensslErrorMessage(); 11854aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("EVP_DigestUpdate %dst optional block failed", i); 11954aa6d63Sopenharmony_ci return outLen; 12054aa6d63Sopenharmony_ci } 12154aa6d63Sopenharmony_ci } 12254aa6d63Sopenharmony_ci if (EVP_DigestFinal(digestParameter.ctxPtr, out, &outLen) <= 0) { 12354aa6d63Sopenharmony_ci GetOpensslErrorMessage(); 12454aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("EVP_DigestFinal failed"); 12554aa6d63Sopenharmony_ci outLen = 0; 12654aa6d63Sopenharmony_ci } 12754aa6d63Sopenharmony_ci return outLen; 12854aa6d63Sopenharmony_ci} 12954aa6d63Sopenharmony_ci 13054aa6d63Sopenharmony_civoid DigestCommon::GetOpensslErrorMessage() 13154aa6d63Sopenharmony_ci{ 13254aa6d63Sopenharmony_ci unsigned long retOpenssl; 13354aa6d63Sopenharmony_ci char errOpenssl[OPENSSL_ERR_MESSAGE_MAX_LEN]; 13454aa6d63Sopenharmony_ci while ((retOpenssl = ERR_get_error()) != 0) { 13554aa6d63Sopenharmony_ci ERR_error_string(retOpenssl, errOpenssl); 13654aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("openssl err: %lu, message: %s", retOpenssl, errOpenssl); 13754aa6d63Sopenharmony_ci } 13854aa6d63Sopenharmony_ci} 13954aa6d63Sopenharmony_ci 14054aa6d63Sopenharmony_ciint32_t DigestCommon::GetDigestAlgorithmId(int32_t signAlgorithm) 14154aa6d63Sopenharmony_ci{ 14254aa6d63Sopenharmony_ci switch (signAlgorithm) { 14354aa6d63Sopenharmony_ci case ALGORITHM_SHA256_WITH_ECDSA: 14454aa6d63Sopenharmony_ci case ALGORITHM_SHA256_WITH_DSA: 14554aa6d63Sopenharmony_ci return NID_sha256; 14654aa6d63Sopenharmony_ci case ALGORITHM_SHA384_WITH_ECDSA: 14754aa6d63Sopenharmony_ci case ALGORITHM_SHA384_WITH_DSA: 14854aa6d63Sopenharmony_ci return NID_sha384; 14954aa6d63Sopenharmony_ci case ALGORITHM_SHA512_WITH_ECDSA: 15054aa6d63Sopenharmony_ci case ALGORITHM_SHA512_WITH_DSA: 15154aa6d63Sopenharmony_ci return NID_sha512; 15254aa6d63Sopenharmony_ci default: 15354aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("signAlgorithm: %d error", signAlgorithm); 15454aa6d63Sopenharmony_ci return NID_undef; 15554aa6d63Sopenharmony_ci } 15654aa6d63Sopenharmony_ci} 15754aa6d63Sopenharmony_ci 15854aa6d63Sopenharmony_cistd::string DigestCommon::GetDigestAlgorithmString(int32_t signAlgorithm) 15954aa6d63Sopenharmony_ci{ 16054aa6d63Sopenharmony_ci switch (signAlgorithm) { 16154aa6d63Sopenharmony_ci case ALGORITHM_SHA256_WITH_ECDSA: 16254aa6d63Sopenharmony_ci return "SHA-256"; 16354aa6d63Sopenharmony_ci case ALGORITHM_SHA384_WITH_ECDSA: 16454aa6d63Sopenharmony_ci return "SHA-384"; 16554aa6d63Sopenharmony_ci case ALGORITHM_SHA512_WITH_ECDSA: 16654aa6d63Sopenharmony_ci return "SHA-512"; 16754aa6d63Sopenharmony_ci default: 16854aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("signAlgorithm: %d error", signAlgorithm); 16954aa6d63Sopenharmony_ci return ""; 17054aa6d63Sopenharmony_ci } 17154aa6d63Sopenharmony_ci} 17254aa6d63Sopenharmony_ci} // namespace SignatureTools 17354aa6d63Sopenharmony_ci} // namespace OHOS