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
19 namespace OHOS {
20 namespace SignatureTools {
21 const int32_t DigestCommon::OPENSSL_ERR_MESSAGE_MAX_LEN = 1024;
22
GetDigestAlgorithmOutputSizeBytes(int32_t nId)23 int32_t DigestCommon::GetDigestAlgorithmOutputSizeBytes(int32_t nId)
24 {
25 return EVP_MD_size(EVP_get_digestbynid(nId));
26 }
27
CheckDigestParameter(const DigestParameter & digestParameter)28 bool 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
DigestInit(const DigestParameter & digestParameter)41 bool 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 */
DigestUpdate(const DigestParameter & digestParameter,const unsigned char content[],int32_t len)55 bool 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
GetDigest(const DigestParameter & digestParameter,unsigned char (& out)[EVP_MAX_MD_SIZE])73 int32_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
GetDigest(const ByteBuffer & chunk,const std::vector<OptionalBlock> & optionalBlocks,const DigestParameter & digestParameter,unsigned char (& out)[EVP_MAX_MD_SIZE])88 int32_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
GetOpensslErrorMessage()130 void 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
GetDigestAlgorithmId(int32_t signAlgorithm)140 int32_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
GetDigestAlgorithmString(int32_t signAlgorithm)158 std::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