• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_HMAC_C
23 
24 #include "hks_openssl_hmac.h"
25 
26 #include <openssl/evp.h>
27 #include <openssl/hmac.h>
28 #include <openssl/ossl_typ.h>
29 #include <stddef.h>
30 
31 #include "hks_common_check.h"
32 #include "hks_log.h"
33 #include "hks_mem.h"
34 #include "hks_openssl_common.h"
35 #include "hks_openssl_engine.h"
36 #include "hks_template.h"
37 
38 struct HksOpensslHmacCtx {
39     uint32_t digestLen;
40     void *append;
41 };
42 
HmacCheckBuffer(const struct HksBlob * key,const struct HksBlob * msg,const struct HksBlob * mac)43 static int32_t HmacCheckBuffer(const struct HksBlob *key, const struct HksBlob *msg, const struct HksBlob *mac)
44 {
45     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(key), HKS_ERROR_INVALID_ARGUMENT, "Invalid key point")
46     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(msg), HKS_ERROR_INVALID_ARGUMENT, "Invalid msg")
47     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(mac), HKS_ERROR_INVALID_ARGUMENT, "Invalid mac")
48     return HKS_SUCCESS;
49 }
50 
HmacGenKeyCheckParam(const struct HksKeySpec * spec)51 static int32_t HmacGenKeyCheckParam(const struct HksKeySpec *spec)
52 {
53     if ((spec->keyLen == 0) || (spec->keyLen % BIT_NUM_OF_UINT8 != 0)) {
54         HKS_LOG_E("keyLen is wrong, len = %" LOG_PUBLIC "u", spec->keyLen);
55         return HKS_ERROR_INVALID_ARGUMENT;
56     }
57     return HKS_SUCCESS;
58 }
59 
60 #ifdef HKS_SUPPORT_HMAC_GENERATE_KEY
HksOpensslHmacGenerateKey(const struct HksKeySpec * spec,struct HksBlob * key)61 int32_t HksOpensslHmacGenerateKey(const struct HksKeySpec *spec, struct HksBlob *key)
62 {
63     HKS_IF_NOT_SUCC_LOGE_RETURN(HmacGenKeyCheckParam(spec),
64         HKS_ERROR_INVALID_ARGUMENT, "aes generate key invalid params!")
65 
66     return HksOpensslGenerateRandomKey(spec->keyLen, key);
67 }
68 #endif /* HKS_SUPPORT_HMAC_GENERATE_KEY */
69 
HmacCheckParam(const struct HksBlob * key,uint32_t alg,const struct HksBlob * msg,const struct HksBlob * mac)70 static int32_t HmacCheckParam(
71     const struct HksBlob *key, uint32_t alg, const struct HksBlob *msg, const struct HksBlob *mac)
72 {
73     HKS_IF_NOT_SUCC_LOGE_RETURN(HmacCheckBuffer(key, msg, mac), HKS_ERROR_INVALID_ARGUMENT, "Invalid Buffer Info")
74 
75     if ((alg != HKS_DIGEST_SHA1) && (alg != HKS_DIGEST_SHA224) && (alg != HKS_DIGEST_SHA256) &&
76         (alg != HKS_DIGEST_SHA384) && (alg != HKS_DIGEST_SHA512) && (alg != HKS_DIGEST_SM3)) {
77         HKS_LOG_E("Invalid alg(0x%" LOG_PUBLIC "x)", alg);
78         return HKS_ERROR_INVALID_ARGUMENT;
79     }
80 
81     uint32_t digestLen;
82     HKS_IF_NOT_SUCC_LOGE_RETURN(HksGetDigestLen(alg, &digestLen),
83         HKS_ERROR_INVALID_ARGUMENT, "Invalid alg(0x%" LOG_PUBLIC "x)", alg)
84 
85     if (mac->size < digestLen) {
86         HKS_LOG_E("invalid mac->size(0x%" LOG_PUBLIC "x) for digestLen(0x%" LOG_PUBLIC "x)", mac->size, digestLen);
87         return HKS_ERROR_INVALID_ARGUMENT;
88     }
89     return HKS_SUCCESS;
90 }
91 
92 #if defined(HKS_SUPPORT_HMAC_SHA1) || defined(HKS_SUPPORT_HMAC_SHA224) || defined(HKS_SUPPORT_HMAC_SHA256) || \
93     defined(HKS_SUPPORT_HMAC_SHA384) || defined(HKS_SUPPORT_HMAC_SHA512) || defined(HKS_SUPPORT_HMAC_SM3)
HksOpensslHmac(const struct HksBlob * key,uint32_t digestAlg,const struct HksBlob * msg,struct HksBlob * mac)94 int32_t HksOpensslHmac(const struct HksBlob *key, uint32_t digestAlg, const struct HksBlob *msg, struct HksBlob *mac)
95 {
96     HKS_IF_NOT_SUCC_RETURN(HmacCheckParam(key, digestAlg, msg, mac), HKS_ERROR_INVALID_ARGUMENT)
97 
98     const EVP_MD *opensslAlg = NULL;
99     if (digestAlg == HKS_DIGEST_SM3) {
100         opensslAlg = EVP_sm3();
101     } else {
102         opensslAlg = GetOpensslAlg(digestAlg);
103     }
104 
105     HKS_IF_NULL_LOGE_RETURN(opensslAlg, HKS_ERROR_CRYPTO_ENGINE_ERROR, "hmac get openssl algorithm failed")
106 
107     uint8_t *hmacData = HMAC(opensslAlg, key->data, (int32_t)key->size, msg->data, msg->size, mac->data, &mac->size);
108     HKS_IF_NULL_LOGE_RETURN(hmacData, HKS_ERROR_CRYPTO_ENGINE_ERROR, "hmac process failed.")
109     return HKS_SUCCESS;
110 }
111 
HksOpensslHmacInit(void ** cryptoCtx,const struct HksBlob * key,uint32_t digestAlg)112 int32_t HksOpensslHmacInit(void **cryptoCtx, const struct HksBlob *key, uint32_t digestAlg)
113 {
114     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(key), HKS_ERROR_INVALID_ARGUMENT, "Invalid key point")
115 
116     if ((digestAlg != HKS_DIGEST_SHA1) && (digestAlg != HKS_DIGEST_SHA224) && (digestAlg != HKS_DIGEST_SHA256) &&
117         (digestAlg != HKS_DIGEST_SHA384) && (digestAlg != HKS_DIGEST_SHA512) && (digestAlg != HKS_DIGEST_SM3)) {
118         HKS_LOG_E("Invalid alg(0x%" LOG_PUBLIC "x)", digestAlg);
119         return HKS_ERROR_INVALID_ARGUMENT;
120     }
121 
122     const EVP_MD *opensslAlg = NULL;
123     if (digestAlg == HKS_DIGEST_SM3) {
124         opensslAlg = EVP_sm3();
125     } else {
126         opensslAlg = GetOpensslAlg(digestAlg);
127     }
128 
129     HKS_IF_NULL_LOGE_RETURN(opensslAlg, HKS_ERROR_CRYPTO_ENGINE_ERROR, "hmac_init get openssl algorithm fail")
130 
131     uint32_t digestLen;
132     HKS_IF_NOT_SUCC_LOGE_RETURN(HksGetDigestLen(digestAlg, &digestLen),
133         HKS_ERROR_INVALID_ARGUMENT, "Invalid alg(0x%" LOG_PUBLIC "x)", digestAlg)
134 
135     HMAC_CTX *tmpCtx = NULL;
136     HKS_IF_NULL_LOGE_RETURN((tmpCtx = HMAC_CTX_new()),
137         HKS_ERROR_CRYPTO_ENGINE_ERROR, "initialize HksOpensslHmacCtx failed")
138 
139     if (!HMAC_Init_ex(tmpCtx, key->data, (int32_t)key->size, opensslAlg, NULL)) {
140         HKS_LOG_E("openssl hmac init failed.");
141         HMAC_CTX_free(tmpCtx);
142         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
143     }
144 
145     struct HksOpensslHmacCtx *outCtx = (struct HksOpensslHmacCtx *)HksMalloc(
146         sizeof(struct HksOpensslHmacCtx));
147 
148     if (outCtx == NULL) {
149         HKS_LOG_E("initialize HksOpensslHmacCtx failed");
150         HMAC_CTX_free(tmpCtx);
151         return HKS_ERROR_MALLOC_FAIL;
152     }
153 
154     outCtx->digestLen = digestLen;
155     outCtx->append = (void *)tmpCtx;
156     *cryptoCtx = (void *)outCtx;
157 
158     return HKS_SUCCESS;
159 }
160 
HksOpensslHmacUpdate(void * cryptoCtx,const struct HksBlob * msg)161 int32_t HksOpensslHmacUpdate(void *cryptoCtx, const struct HksBlob *msg)
162 {
163     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(msg), HKS_ERROR_INVALID_ARGUMENT, "Invalid key point")
164 
165     struct HksOpensslHmacCtx *hmacCtx = (struct HksOpensslHmacCtx *)cryptoCtx;
166     HKS_IF_NULL_LOGE_RETURN(hmacCtx, HKS_ERROR_NULL_POINTER, "hmacCtx invalid")
167 
168     HMAC_CTX *context = (HMAC_CTX *)hmacCtx->append;
169     HKS_IF_NULL_LOGE_RETURN(context, HKS_FAILURE, "context is null")
170 
171     int hmacData = HMAC_Update(context, msg->data, msg->size);
172     if (!hmacData) {
173         HKS_LOG_E("hmac update failed.");
174         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
175     }
176     return HKS_SUCCESS;
177 }
178 
HksOpensslHmacFinal(void ** cryptoCtx,struct HksBlob * msg,struct HksBlob * mac)179 int32_t HksOpensslHmacFinal(void **cryptoCtx, struct HksBlob *msg, struct HksBlob *mac)
180 {
181     if ((cryptoCtx == NULL) || (*cryptoCtx == NULL)) {
182         return HKS_ERROR_NULL_POINTER;
183     }
184 
185     struct HksOpensslHmacCtx *hmacCtx = (struct HksOpensslHmacCtx *)*cryptoCtx;
186     if (hmacCtx == NULL) {
187         HKS_LOG_E("hmacCtx invalid");
188         HKS_FREE(*cryptoCtx);
189         return HKS_ERROR_NULL_POINTER;
190     }
191 
192     HMAC_CTX *context = (HMAC_CTX *)hmacCtx->append;
193     if (context == NULL) {
194         HKS_LOG_E("context is null");
195         HKS_FREE(*cryptoCtx);
196         return HKS_FAILURE;
197     }
198 
199     if (msg == NULL || HksOpensslCheckBlob(mac) != HKS_SUCCESS) {
200         HKS_LOG_E("Invalid msg or mac point");
201         HksOpensslHmacHalFreeCtx(cryptoCtx);
202         return HKS_ERROR_INVALID_ARGUMENT;
203     }
204 
205     int hmacData;
206     if (msg->size != 0) {
207         hmacData = HMAC_Update(context, msg->data, msg->size);
208         if (!hmacData) {
209             HKS_LOG_E("hmac final update failed.");
210             HksOpensslHmacHalFreeCtx(cryptoCtx);
211             return HKS_ERROR_CRYPTO_ENGINE_ERROR;
212         }
213     }
214 
215     hmacData = HMAC_Final(context, mac->data, &mac->size);
216     if (!hmacData) {
217         HKS_LOG_E("hmac final failed.");
218         HksOpensslHmacHalFreeCtx(cryptoCtx);
219         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
220     }
221 
222     HksOpensslHmacHalFreeCtx(cryptoCtx);
223     return HKS_SUCCESS;
224 }
225 
HksOpensslHmacHalFreeCtx(void ** cryptoCtx)226 void HksOpensslHmacHalFreeCtx(void **cryptoCtx)
227 {
228     if (cryptoCtx == NULL || *cryptoCtx == NULL) {
229         HKS_LOG_E("Openssl hmac free ctx is null");
230         return;
231     }
232 
233     struct HksOpensslHmacCtx *opensslHmacCtx = (struct HksOpensslHmacCtx *)*cryptoCtx;
234     if (opensslHmacCtx->append != NULL) {
235         HMAC_CTX_free((HMAC_CTX *)opensslHmacCtx->append);
236         opensslHmacCtx->append = NULL;
237     }
238 
239     HKS_FREE(*cryptoCtx);
240 }
241 #endif /* HKS_SUPPORT_HMAC_SHA1 */
242 #endif /* HKS_SUPPORT_HMAC_C */