• 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 #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