1 /*
2 * Copyright (c) 2021-2022 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
16 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21
22 #ifdef HKS_SUPPORT_HASH_C
23
24 #include "hks_openssl_hash.h"
25
26 #include <openssl/evp.h>
27 #include <openssl/ossl_typ.h>
28 #include <stddef.h>
29
30 #include "hks_log.h"
31 #include "hks_openssl_engine.h"
32 #include "hks_template.h"
33
CheckDigestAlg(uint32_t alg)34 static int32_t CheckDigestAlg(uint32_t alg)
35 {
36 switch (alg) {
37 #ifdef HKS_SUPPORT_HASH_SHA1
38 case HKS_DIGEST_SHA1:
39 #endif
40 #ifdef HKS_SUPPORT_HASH_SHA224
41 case HKS_DIGEST_SHA224:
42 #endif
43 #ifdef HKS_SUPPORT_HASH_SHA256
44 case HKS_DIGEST_SHA256:
45 #endif
46 #ifdef HKS_SUPPORT_HASH_SHA384
47 case HKS_DIGEST_SHA384:
48 #endif
49 #ifdef HKS_SUPPORT_HASH_SHA512
50 case HKS_DIGEST_SHA512:
51 #endif
52 #ifdef HKS_SUPPORT_HASH_MD5
53 case HKS_DIGEST_MD5:
54 #endif
55 #ifdef HKS_SUPPORT_HASH_SM3
56 case HKS_DIGEST_SM3:
57 #endif
58 break;
59 default:
60 HKS_LOG_E("Unsupport HASH Type!");
61 return HKS_ERROR_INVALID_DIGEST;
62 }
63 return HKS_SUCCESS;
64 }
65
HashCheckParam(uint32_t alg,const struct HksBlob * msg,struct HksBlob * hash)66 static int32_t HashCheckParam(uint32_t alg, const struct HksBlob *msg, struct HksBlob *hash)
67 {
68 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckDigestAlg(alg), HKS_ERROR_INVALID_DIGEST, "Unsupport HASH Type!")
69
70 HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(hash), HKS_ERROR_INVALID_ARGUMENT, "Invalid param hash!")
71
72 HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(msg), HKS_ERROR_INVALID_ARGUMENT, "Invalid param msg!")
73 return HKS_SUCCESS;
74 }
75
HksOpensslHash(uint32_t alg,const struct HksBlob * msg,struct HksBlob * hash)76 int32_t HksOpensslHash(uint32_t alg, const struct HksBlob *msg, struct HksBlob *hash)
77 {
78 int32_t ret = HashCheckParam(alg, msg, hash);
79 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "Invalid Params!")
80
81 const EVP_MD *opensslAlg = GetOpensslAlg(alg);
82 HKS_IF_NULL_LOGE_RETURN(opensslAlg, HKS_ERROR_CRYPTO_ENGINE_ERROR, "get openssl algorithm fail")
83
84 ret = EVP_Digest(msg->data, msg->size, hash->data, &hash->size, opensslAlg, NULL);
85 if (ret != HKS_OPENSSL_SUCCESS) {
86 HksLogOpensslError();
87 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
88 }
89 return HKS_SUCCESS;
90 }
91
HksOpensslHashInit(void ** cryptoCtx,uint32_t alg)92 int32_t HksOpensslHashInit(void **cryptoCtx, uint32_t alg)
93 {
94 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckDigestAlg(alg), HKS_ERROR_INVALID_DIGEST, "Unsupport HASH Type!")
95
96 const EVP_MD *opensslAlg = NULL;
97 if (alg == HKS_DIGEST_SM3) {
98 opensslAlg = EVP_sm3();
99 } else {
100 opensslAlg = GetOpensslAlg(alg);
101 }
102
103 HKS_IF_NULL_LOGE_RETURN(opensslAlg, HKS_ERROR_CRYPTO_ENGINE_ERROR, "hash_init get openssl algorithm fail")
104
105 EVP_MD_CTX *tmpctx = EVP_MD_CTX_new();
106 HKS_IF_NULL_RETURN(opensslAlg, HKS_ERROR_NULL_POINTER)
107
108 EVP_MD_CTX_set_flags(tmpctx, EVP_MD_CTX_FLAG_ONESHOT);
109 int32_t ret = EVP_DigestInit_ex(tmpctx, opensslAlg, NULL);
110 if (ret != HKS_OPENSSL_SUCCESS) {
111 HksLogOpensslError();
112 EVP_MD_CTX_free(tmpctx);
113 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
114 }
115 *cryptoCtx = (void*)tmpctx;
116 return HKS_SUCCESS;
117 }
118
HksOpensslHashUpdate(void * cryptoCtx,const struct HksBlob * msg)119 int32_t HksOpensslHashUpdate(void *cryptoCtx, const struct HksBlob *msg)
120 {
121 HKS_IF_NULL_LOGE_RETURN(cryptoCtx, HKS_ERROR_INVALID_ARGUMENT, "Invalid param cryptoCtx!")
122
123 HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(msg),
124 HKS_ERROR_INVALID_ARGUMENT, "Invalid param msg!")
125
126 int32_t ret = EVP_DigestUpdate(cryptoCtx, msg->data, msg->size);
127 if (ret != HKS_OPENSSL_SUCCESS) {
128 HksLogOpensslError();
129 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
130 }
131 return HKS_SUCCESS;
132 }
133
HksOpensslHashFinal(void ** cryptoCtx,const struct HksBlob * msg,struct HksBlob * hash)134 int32_t HksOpensslHashFinal(void **cryptoCtx, const struct HksBlob *msg, struct HksBlob *hash)
135 {
136 if (cryptoCtx == NULL || *cryptoCtx == NULL) {
137 HKS_LOG_E("Invalid param cryptoCtx!");
138 return HKS_ERROR_INVALID_ARGUMENT;
139 }
140
141 if (msg == NULL) {
142 HKS_LOG_E("Invalid param msg!");
143 EVP_MD_CTX_free((EVP_MD_CTX *)*cryptoCtx);
144 *cryptoCtx = NULL;
145 return HKS_ERROR_INVALID_ARGUMENT;
146 }
147 if (HksOpensslCheckBlob(hash) != HKS_SUCCESS) {
148 HKS_LOG_E("Invalid param hash!");
149 EVP_MD_CTX_free((EVP_MD_CTX *)*cryptoCtx);
150 *cryptoCtx = NULL;
151 return HKS_ERROR_INVALID_ARGUMENT;
152 }
153
154 int32_t ret;
155 if (msg->size != 0) {
156 ret = EVP_DigestUpdate((EVP_MD_CTX *)*cryptoCtx, msg->data, msg->size);
157 if (ret != HKS_OPENSSL_SUCCESS) {
158 HksLogOpensslError();
159 EVP_MD_CTX_free((EVP_MD_CTX *)*cryptoCtx);
160 *cryptoCtx = NULL;
161 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
162 }
163 }
164
165 ret = EVP_DigestFinal_ex((EVP_MD_CTX *)*cryptoCtx, hash->data, &hash->size);
166 if (ret != HKS_OPENSSL_SUCCESS) {
167 HksLogOpensslError();
168 EVP_MD_CTX_free((EVP_MD_CTX *)*cryptoCtx);
169 *cryptoCtx = NULL;
170 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
171 }
172
173 EVP_MD_CTX_free((EVP_MD_CTX *)*cryptoCtx);
174 *cryptoCtx = NULL;
175 return HKS_SUCCESS;
176 }
177
HksOpensslHashFreeCtx(void ** cryptoCtx)178 void HksOpensslHashFreeCtx(void **cryptoCtx)
179 {
180 if (cryptoCtx == NULL || *cryptoCtx == NULL) {
181 HKS_LOG_E("Openssl Hash freeCtx param error");
182 return;
183 }
184
185 if (*cryptoCtx != NULL) {
186 EVP_MD_CTX_free((EVP_MD_CTX *)*cryptoCtx);
187 *cryptoCtx = NULL;
188 }
189 }
190 #endif