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#include "digest_common.h" 16#include "signature_tools_log.h" 17#include "openssl/err.h" 18 19namespace OHOS { 20namespace SignatureTools { 21const int32_t DigestCommon::OPENSSL_ERR_MESSAGE_MAX_LEN = 1024; 22 23int32_t DigestCommon::GetDigestAlgorithmOutputSizeBytes(int32_t nId) 24{ 25 return EVP_MD_size(EVP_get_digestbynid(nId)); 26} 27 28bool DigestCommon::CheckDigestParameter(const DigestParameter& digestParameter) 29{ 30 if (digestParameter.md == nullptr) { 31 SIGNATURE_TOOLS_LOGE("md is nullptr"); 32 return false; 33 } 34 if (digestParameter.ctxPtr == nullptr) { 35 SIGNATURE_TOOLS_LOGE("ctxPtr is nullptr"); 36 return false; 37 } 38 return true; 39} 40 41bool DigestCommon::DigestInit(const DigestParameter& digestParameter) 42{ 43 if (!CheckDigestParameter(digestParameter)) { 44 return false; 45 } 46 if (EVP_DigestInit(digestParameter.ctxPtr, digestParameter.md) <= 0) { 47 GetOpensslErrorMessage(); 48 SIGNATURE_TOOLS_LOGE("EVP_DigestInit failed"); 49 return false; 50 } 51 return true; 52} 53 54/* the caller must ensure that EVP_DigestInit was called before calling this function */ 55bool DigestCommon::DigestUpdate(const DigestParameter& digestParameter, 56 const unsigned char content[], int32_t len) 57{ 58 if (content == nullptr) { 59 SIGNATURE_TOOLS_LOGE("content is nullptr"); 60 return false; 61 } 62 if (!CheckDigestParameter(digestParameter)) { 63 return false; 64 } 65 if (EVP_DigestUpdate(digestParameter.ctxPtr, content, len) <= 0) { 66 GetOpensslErrorMessage(); 67 SIGNATURE_TOOLS_LOGE("EVP_DigestUpdate failed"); 68 return false; 69 } 70 return true; 71} 72 73int32_t DigestCommon::GetDigest(const DigestParameter& digestParameter, 74 unsigned char(&out)[EVP_MAX_MD_SIZE]) 75{ 76 uint32_t outLen = 0; 77 if (!CheckDigestParameter(digestParameter)) { 78 return outLen; 79 } 80 if (EVP_DigestFinal(digestParameter.ctxPtr, out, &outLen) <= 0) { 81 GetOpensslErrorMessage(); 82 SIGNATURE_TOOLS_LOGE("EVP_DigestFinal failed"); 83 outLen = 0; 84 } 85 return outLen; 86} 87 88int32_t DigestCommon::GetDigest(const ByteBuffer& chunk, 89 const std::vector<OptionalBlock>& optionalBlocks, 90 const DigestParameter& digestParameter, 91 unsigned char(&out)[EVP_MAX_MD_SIZE]) 92{ 93 int32_t chunkLen = chunk.Remaining(); 94 uint32_t outLen = 0; 95 if (digestParameter.md == nullptr) { 96 SIGNATURE_TOOLS_LOGE("md is nullprt"); 97 return outLen; 98 } 99 if (digestParameter.ctxPtr == nullptr) { 100 SIGNATURE_TOOLS_LOGE("ctxPtr is nullprt"); 101 return outLen; 102 } 103 if (EVP_DigestInit(digestParameter.ctxPtr, digestParameter.md) <= 0) { 104 GetOpensslErrorMessage(); 105 SIGNATURE_TOOLS_LOGE("EVP_DigestInit failed"); 106 return outLen; 107 } 108 if (EVP_DigestUpdate(digestParameter.ctxPtr, chunk.GetBufferPtr(), chunkLen) <= 0) { 109 GetOpensslErrorMessage(); 110 SIGNATURE_TOOLS_LOGE("EVP_DigestUpdate chunk failed"); 111 return outLen; 112 } 113 for (int32_t i = 0; i < static_cast<int>(optionalBlocks.size()); i++) { 114 chunkLen = optionalBlocks[i].optionalBlockValue.GetCapacity(); 115 if (EVP_DigestUpdate(digestParameter.ctxPtr, optionalBlocks[i].optionalBlockValue.GetBufferPtr(), 116 chunkLen) <= 0) { 117 GetOpensslErrorMessage(); 118 SIGNATURE_TOOLS_LOGE("EVP_DigestUpdate %dst optional block failed", i); 119 return outLen; 120 } 121 } 122 if (EVP_DigestFinal(digestParameter.ctxPtr, out, &outLen) <= 0) { 123 GetOpensslErrorMessage(); 124 SIGNATURE_TOOLS_LOGE("EVP_DigestFinal failed"); 125 outLen = 0; 126 } 127 return outLen; 128} 129 130void DigestCommon::GetOpensslErrorMessage() 131{ 132 unsigned long retOpenssl; 133 char errOpenssl[OPENSSL_ERR_MESSAGE_MAX_LEN]; 134 while ((retOpenssl = ERR_get_error()) != 0) { 135 ERR_error_string(retOpenssl, errOpenssl); 136 SIGNATURE_TOOLS_LOGE("openssl err: %lu, message: %s", retOpenssl, errOpenssl); 137 } 138} 139 140int32_t DigestCommon::GetDigestAlgorithmId(int32_t signAlgorithm) 141{ 142 switch (signAlgorithm) { 143 case ALGORITHM_SHA256_WITH_ECDSA: 144 case ALGORITHM_SHA256_WITH_DSA: 145 return NID_sha256; 146 case ALGORITHM_SHA384_WITH_ECDSA: 147 case ALGORITHM_SHA384_WITH_DSA: 148 return NID_sha384; 149 case ALGORITHM_SHA512_WITH_ECDSA: 150 case ALGORITHM_SHA512_WITH_DSA: 151 return NID_sha512; 152 default: 153 SIGNATURE_TOOLS_LOGE("signAlgorithm: %d error", signAlgorithm); 154 return NID_undef; 155 } 156} 157 158std::string DigestCommon::GetDigestAlgorithmString(int32_t signAlgorithm) 159{ 160 switch (signAlgorithm) { 161 case ALGORITHM_SHA256_WITH_ECDSA: 162 return "SHA-256"; 163 case ALGORITHM_SHA384_WITH_ECDSA: 164 return "SHA-384"; 165 case ALGORITHM_SHA512_WITH_ECDSA: 166 return "SHA-512"; 167 default: 168 SIGNATURE_TOOLS_LOGE("signAlgorithm: %d error", signAlgorithm); 169 return ""; 170 } 171} 172} // namespace SignatureTools 173} // namespace OHOS