1 /*
2 * Copyright (c) 2020-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 #define HUKS_DISABLE_LOG_AT_FILE_TO_REDUCE_ROM_SIZE
16
17 #ifdef HKS_CONFIG_FILE
18 #include HKS_CONFIG_FILE
19 #else
20 #include "hks_config.h"
21 #endif
22
23 #ifdef HKS_SUPPORT_HMAC_C
24
25 #ifdef HUKS_LOG_MINI_EXT_ENABLED
26 #include "log.h"
27 #endif
28
29 #include "hks_mbedtls_hmac.h"
30
31 #include <mbedtls/md.h>
32 #include <securec.h>
33
34 #include "hks_common_check.h"
35 #include "hks_log.h"
36 #include "hks_mbedtls_common.h"
37 #include "hks_mem.h"
38 #include "hks_template.h"
39
40 struct HksMbedtlsHmacCtx {
41 uint32_t digestAlg;
42 void *append;
43 } HksMbedtlsHmacCtx;
44
45 #ifdef HKS_SUPPORT_HMAC_GENERATE_KEY
HksMbedtlsHmacGenerateKey(const struct HksKeySpec * spec,struct HksBlob * key)46 int32_t HksMbedtlsHmacGenerateKey(const struct HksKeySpec *spec, struct HksBlob *key)
47 {
48 if ((spec->keyLen == 0) || (spec->keyLen % HKS_BITS_PER_BYTE != 0)) {
49 return HKS_ERROR_INVALID_ARGUMENT;
50 }
51
52 const uint32_t keyByteLen = spec->keyLen / HKS_BITS_PER_BYTE;
53
54 uint8_t *outKey = (uint8_t *)HksMalloc(keyByteLen);
55 HKS_IF_NULL_RETURN(outKey, HKS_ERROR_MALLOC_FAIL)
56
57 mbedtls_entropy_context entropy;
58 mbedtls_ctr_drbg_context ctrDrbg;
59 (void)memset_s(&entropy, sizeof(mbedtls_entropy_context), 0, sizeof(mbedtls_entropy_context));
60 (void)memset_s(&ctrDrbg, sizeof(mbedtls_ctr_drbg_context), 0, sizeof(mbedtls_ctr_drbg_context));
61 int32_t ret = HksCtrDrbgSeed(&ctrDrbg, &entropy);
62 if (ret != HKS_SUCCESS) {
63 HKS_FREE(outKey);
64 return ret;
65 }
66
67 do {
68 ret = mbedtls_ctr_drbg_random(&ctrDrbg, outKey, keyByteLen);
69 if (ret != HKS_MBEDTLS_SUCCESS) {
70 HKS_LOG_E("Mbedtls ctr drbg random failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
71 #ifdef HUKS_LOG_MINI_EXT_ENABLED
72 HILOG_ERROR(HILOG_MODULE_SCY, "Mbedtls ctr drbg random failed! mbedtls ret = 0x%{public}X", ret);
73 #endif
74 (void)memset_s(outKey, keyByteLen, 0, keyByteLen);
75 HKS_FREE(outKey);
76 break;
77 }
78
79 key->data = outKey;
80 key->size = keyByteLen;
81 } while (0);
82
83 mbedtls_ctr_drbg_free(&ctrDrbg);
84 mbedtls_entropy_free(&entropy);
85 return ret;
86 }
87 #endif /* HKS_SUPPORT_HMAC_GENERATE_KEY */
88
HksMbedtlsHmac(const struct HksBlob * key,uint32_t digestAlg,const struct HksBlob * msg,struct HksBlob * mac)89 int32_t HksMbedtlsHmac(const struct HksBlob *key,
90 uint32_t digestAlg, const struct HksBlob *msg, struct HksBlob *mac)
91 {
92 /* input params have been checked */
93 uint32_t mbedtlsAlg;
94 int32_t ret = HksToMbedtlsDigestAlg(digestAlg, &mbedtlsAlg);
95 HKS_IF_NOT_SUCC_RETURN(ret, ret)
96
97 ret = mbedtls_md_hmac(mbedtls_md_info_from_type((mbedtls_md_type_t)mbedtlsAlg),
98 key->data, key->size, msg->data, msg->size, mac->data);
99 if (ret != HKS_MBEDTLS_SUCCESS) {
100 HKS_LOG_E("Mbedtls hmac failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
101 #ifdef HUKS_LOG_MINI_EXT_ENABLED
102 HILOG_ERROR(HILOG_MODULE_SCY, "Mbedtls hmac failed! mbedtls ret = 0x%{public}X", ret);
103 #endif
104 (void)memset_s(mac->data, mac->size, 0, mac->size);
105 return ret;
106 }
107
108 ret = HksGetDigestLen(digestAlg, &(mac->size));
109 if (ret != HKS_SUCCESS) {
110 HKS_LOG_E("Get digest len failed!");
111 (void)memset_s(mac->data, mac->size, 0, mac->size);
112 }
113
114 return ret;
115 }
116
HksMbedtlsHmacInit(void ** cryptoCtx,const struct HksBlob * key,uint32_t digestAlg)117 int32_t HksMbedtlsHmacInit(void **cryptoCtx, const struct HksBlob *key, uint32_t digestAlg)
118 {
119 /* input params have been checked */
120 uint32_t mbedtlsAlg;
121 int32_t ret = HksToMbedtlsDigestAlg(digestAlg, &mbedtlsAlg);
122 HKS_IF_NOT_SUCC_RETURN(ret, ret)
123
124 if (mbedtls_md_info_from_type((mbedtls_md_type_t)mbedtlsAlg) == NULL) {
125 HKS_LOG_E("Mbedtls hmac engine info failed!");
126 return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
127 }
128
129 mbedtls_md_context_t *hmacCtx = (mbedtls_md_context_t *)HksMalloc(sizeof(mbedtls_md_context_t));
130 HKS_IF_NULL_LOGE_RETURN(hmacCtx, HKS_ERROR_MALLOC_FAIL, "Mbedtls hmac init hmacCtx malloc fail!")
131
132 mbedtls_md_init(hmacCtx);
133
134 ret = mbedtls_md_setup(hmacCtx, mbedtls_md_info_from_type((mbedtls_md_type_t)mbedtlsAlg), 1);
135 if (ret != HKS_MBEDTLS_SUCCESS) {
136 HKS_LOG_E("Mbedtls hmac setup failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
137 mbedtls_md_free(hmacCtx);
138 HKS_FREE(hmacCtx);
139 return ret;
140 }
141
142 ret = mbedtls_md_hmac_starts(hmacCtx, key->data, key->size);
143 if (ret != HKS_MBEDTLS_SUCCESS) {
144 HKS_LOG_E("Mbedtls hmac start failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
145 mbedtls_md_free(hmacCtx);
146 HKS_FREE(hmacCtx);
147 return ret;
148 }
149
150 struct HksMbedtlsHmacCtx *outCtx = (struct HksMbedtlsHmacCtx *)HksMalloc(sizeof(struct HksMbedtlsHmacCtx));
151 if (outCtx == NULL) {
152 HKS_LOG_E("Mbedtls hmac start failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
153 mbedtls_md_free(hmacCtx);
154 HKS_FREE(hmacCtx);
155 return HKS_ERROR_MALLOC_FAIL;
156 }
157
158 outCtx->digestAlg = digestAlg;
159 outCtx->append = (void *)hmacCtx;
160 *cryptoCtx = (void *)outCtx;
161 return HKS_SUCCESS;
162 }
163
HksMbedtlsHmacUpdate(void * cryptoCtx,const struct HksBlob * msg)164 int32_t HksMbedtlsHmacUpdate(void *cryptoCtx, const struct HksBlob *msg)
165 {
166 struct HksMbedtlsHmacCtx *hctx = (struct HksMbedtlsHmacCtx *)cryptoCtx;
167 mbedtls_md_context_t *hmacCtx = (mbedtls_md_context_t *)hctx->append;
168 HKS_IF_NULL_LOGE_RETURN(hmacCtx, HKS_ERROR_MALLOC_FAIL, "Mbedtls hmac update hmacCtx is null!")
169
170 int32_t ret = mbedtls_md_hmac_update(hmacCtx, msg->data, msg->size);
171 if (ret != HKS_MBEDTLS_SUCCESS) {
172 HKS_LOG_E("Mbedtls hmac start failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
173 return ret;
174 }
175
176 return HKS_SUCCESS;
177 }
178
HksMbedtlsHmacFinal(void ** cryptoCtx,struct HksBlob * msg,struct HksBlob * mac)179 int32_t HksMbedtlsHmacFinal(void **cryptoCtx, struct HksBlob *msg, struct HksBlob *mac)
180 {
181 struct HksMbedtlsHmacCtx *hctx = (struct HksMbedtlsHmacCtx *)*cryptoCtx;
182 mbedtls_md_context_t *hmacCtx = (mbedtls_md_context_t *)hctx->append;
183 if (hmacCtx == NULL) {
184 HKS_FREE(*cryptoCtx);
185 return HKS_ERROR_NULL_POINTER;
186 }
187
188 int32_t ret;
189 if (msg->size != 0) {
190 ret = mbedtls_md_hmac_update(hmacCtx, msg->data, msg->size);
191 if (ret != HKS_MBEDTLS_SUCCESS) {
192 HKS_LOG_E("Mbedtls hmac start failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
193 HksMbedtlsHmacHalFreeCtx(cryptoCtx);
194 return ret;
195 }
196 }
197
198 ret = mbedtls_md_hmac_finish(hmacCtx, mac->data);
199 if (ret != HKS_MBEDTLS_SUCCESS) {
200 HKS_LOG_E("Mbedtls hmac finish failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
201 (void)memset_s(mac->data, mac->size, 0, mac->size);
202 HksMbedtlsHmacHalFreeCtx(cryptoCtx);
203 return ret;
204 }
205
206 ret = HksGetDigestLen(hctx->digestAlg, &(mac->size));
207 if (ret != HKS_SUCCESS) {
208 HKS_LOG_E("Get digest len failed!");
209 HksMbedtlsHmacHalFreeCtx(cryptoCtx);
210 return ret;
211 }
212
213 HksMbedtlsHmacHalFreeCtx(cryptoCtx);
214 return HKS_SUCCESS;
215 }
216
HksMbedtlsHmacHalFreeCtx(void ** cryptoCtx)217 void HksMbedtlsHmacHalFreeCtx(void **cryptoCtx)
218 {
219 if (cryptoCtx == NULL || *cryptoCtx == NULL) {
220 HKS_LOG_E("Mbedtls hmac free ctx is null");
221 return;
222 }
223
224 struct HksMbedtlsHmacCtx *hctx = (struct HksMbedtlsHmacCtx *)*cryptoCtx;
225 if (hctx->append != NULL) {
226 mbedtls_md_free((mbedtls_md_context_t *)hctx->append);
227 HKS_FREE(hctx->append);
228 }
229 HKS_FREE(*cryptoCtx);
230 }
231 #endif /* HKS_SUPPORT_HMAC_C */
232