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 #ifndef USE_HISI_MBED
16 #include "mbedtls/compat-2.x.h"
17 #endif
18 #ifdef HKS_CONFIG_FILE
19 #include HKS_CONFIG_FILE
20 #else
21 #include "hks_config.h"
22 #endif
23 
24 #ifdef _CUT_AUTHENTICATE_
25 #undef HKS_SUPPORT_HASH_C
26 #endif /* _CUT_AUTHENTICATE_ */
27 
28 #ifdef HKS_SUPPORT_HASH_C
29 
30 #include "hks_mbedtls_hash.h"
31 
32 #include <mbedtls/md5.h>
33 #include <mbedtls/sha1.h>
34 #include <mbedtls/sha256.h>
35 #include <mbedtls/sha512.h>
36 
37 #include "hks_common_check.h"
38 #include "hks_log.h"
39 #include "hks_mem.h"
40 #include "hks_mbedtls_common.h"
41 #include "hks_template.h"
42 
43 struct HksMbedtlsHashCtx {
44     uint8_t *append;
45     uint32_t mAlg;
46 } HksMbedtlsHashCtx;
47 
HksMbedtlsHashMd5Init(void ** ctx,uint32_t alg)48 static int32_t HksMbedtlsHashMd5Init(void **ctx, uint32_t alg)
49 {
50     int32_t ret = 0;
51     mbedtls_md5_context *context = (mbedtls_md5_context *)HksMalloc(sizeof(mbedtls_md5_context));
52     HKS_IF_NULL_LOGE_RETURN(context, HKS_ERROR_MALLOC_FAIL, "malloc fail")
53 
54     mbedtls_md5_init(context);
55 
56     ret = mbedtls_md5_starts_ret(context);
57     if (ret != HKS_MBEDTLS_SUCCESS) {
58         HKS_LOG_E("Mbedtls Hash Md5 init starts_ret fail");
59         mbedtls_md5_free(context);
60         if (context != NULL) {
61             HKS_FREE(context);
62         }
63         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
64     }
65 
66     struct HksMbedtlsHashCtx *outCtx = (struct HksMbedtlsHashCtx *)HksMalloc(sizeof(HksMbedtlsHashCtx));
67     if (outCtx == NULL) {
68         HKS_LOG_E("Mbedtls Hash Md5 init malloc fail");
69         mbedtls_md5_free(context);
70         if (context != NULL) {
71             HKS_FREE(context);
72         }
73         return HKS_ERROR_MALLOC_FAIL;
74     }
75 
76     outCtx->append = (void *)context;
77     outCtx->mAlg = alg;
78     *ctx = (void *)outCtx;
79     return HKS_SUCCESS;
80 }
81 
HksMbedtlsHashMd5Update(struct HksMbedtlsHashCtx * ctx,const unsigned char * input,size_t ilen)82 static int32_t HksMbedtlsHashMd5Update(struct HksMbedtlsHashCtx *ctx, const unsigned char *input, size_t ilen)
83 {
84     int32_t ret = 0;
85     mbedtls_md5_context *context = (mbedtls_md5_context *)ctx->append;
86 
87     HKS_IF_NULL_RETURN(context, HKS_ERROR_NULL_POINTER)
88 
89     ret = mbedtls_md5_update_ret(context, input, ilen);
90     if (ret != HKS_MBEDTLS_SUCCESS) {
91         HKS_LOG_E("Mbedtls Hash Md5 update fail");
92         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
93     }
94 
95     return HKS_SUCCESS;
96 }
97 
HksMbedtlsHashMd5Final(struct HksMbedtlsHashCtx * ctx,const struct HksBlob * msg,struct HksBlob * hash)98 static int32_t HksMbedtlsHashMd5Final(struct HksMbedtlsHashCtx *ctx, const struct HksBlob *msg, struct HksBlob *hash)
99 {
100     int32_t ret = 0;
101     mbedtls_md5_context *context = (mbedtls_md5_context *)ctx->append;
102 
103     HKS_IF_NULL_RETURN(context, HKS_ERROR_NULL_POINTER)
104 
105     do {
106         if (msg->size != 0) {
107             ret = mbedtls_md5_update_ret(context, msg->data, msg->size);
108             if (ret != HKS_MBEDTLS_SUCCESS) {
109                 HKS_LOG_E("Mbedtls Hash Md5 finish last data fail");
110                 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
111                 break;
112             }
113         }
114 
115         ret = mbedtls_md5_finish_ret(context, hash->data);
116         if (ret != HKS_MBEDTLS_SUCCESS) {
117             HKS_LOG_E("Mbedtls Hash Md5 finish fail");
118             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
119             break;
120         }
121 
122         ret = HKS_SUCCESS;
123     } while (0);
124 
125     mbedtls_md5_free(context);
126     HKS_FREE(context);
127     ctx->append = NULL;
128 
129     return ret;
130 }
131 
HksMbedtlsHashSha1Init(void ** ctx,uint32_t alg)132 static int32_t HksMbedtlsHashSha1Init(void **ctx, uint32_t alg)
133 {
134     int32_t ret = 0;
135     mbedtls_sha1_context *context = (mbedtls_sha1_context *)HksMalloc(sizeof(mbedtls_sha1_context));
136     HKS_IF_NULL_LOGE_RETURN(context, HKS_ERROR_MALLOC_FAIL, "malloc fail")
137     mbedtls_sha1_init(context);
138 
139     ret = mbedtls_sha1_starts_ret(context);
140     if (ret != HKS_MBEDTLS_SUCCESS) {
141         HKS_LOG_E("Mbedtls Hash Sha1 init start_rat fail");
142         mbedtls_sha1_free(context);
143         if (context != NULL) {
144             HKS_FREE(context);
145         }
146         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
147     }
148 
149     struct HksMbedtlsHashCtx *outCtx = (struct HksMbedtlsHashCtx *)HksMalloc(sizeof(HksMbedtlsHashCtx));
150     if (outCtx == NULL) {
151         HKS_LOG_E("Mbedtls Hash Sha1 init malloc fail");
152         mbedtls_sha1_free(context);
153         if (context != NULL) {
154             HKS_FREE(context);
155         }
156         return HKS_ERROR_MALLOC_FAIL;
157     }
158 
159     outCtx->append = (void *)context;
160     outCtx->mAlg = alg;
161     *ctx = (void *)outCtx;
162 
163     return HKS_SUCCESS;
164 }
165 
HksMbedtlsHashSha1Update(struct HksMbedtlsHashCtx * ctx,const unsigned char * input,size_t ilen)166 static int32_t HksMbedtlsHashSha1Update(struct HksMbedtlsHashCtx *ctx, const unsigned char *input, size_t ilen)
167 {
168     mbedtls_sha1_context *context = (mbedtls_sha1_context *)ctx->append;
169     HKS_IF_NULL_RETURN(context, HKS_ERROR_NULL_POINTER)
170 
171     if (ilen == 0 || input == NULL) {
172         HKS_LOG_E("Mbedtls Hash sha1 input param error");
173         return HKS_ERROR_INVALID_ARGUMENT;
174     }
175 
176     int32_t ret = mbedtls_sha1_update_ret(context, input, ilen);
177     if (ret != HKS_MBEDTLS_SUCCESS) {
178         HKS_LOG_E("Mbedtls Hash sha1 update fail");
179         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
180     }
181 
182     return HKS_SUCCESS;
183 }
184 
HksMbedtlsHashSha1Final(struct HksMbedtlsHashCtx * ctx,const struct HksBlob * msg,struct HksBlob * hash)185 static int32_t HksMbedtlsHashSha1Final(struct HksMbedtlsHashCtx *ctx, const struct HksBlob *msg, struct HksBlob *hash)
186 {
187     mbedtls_sha1_context *context = (mbedtls_sha1_context *)ctx->append;
188     HKS_IF_NULL_RETURN(context, HKS_ERROR_NULL_POINTER)
189 
190     int32_t ret = 0;
191     do {
192         if (hash->data == NULL) {
193             HKS_LOG_E("Mbedtls Hash sha1 output param error");
194             ret = HKS_ERROR_INVALID_ARGUMENT;
195             break;
196         }
197 
198         if (msg->size != 0) {
199             ret = mbedtls_sha1_update_ret(context, msg->data, msg->size);
200             if (ret != HKS_MBEDTLS_SUCCESS) {
201                 HKS_LOG_E("Mbedtls Hash sha1 finish last data fail");
202                 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
203                 break;
204             }
205         }
206 
207         ret = mbedtls_sha1_finish_ret(context, hash->data);
208         if (ret != HKS_MBEDTLS_SUCCESS) {
209             HKS_LOG_E("Mbedtls Hash sha1 finish fail");
210             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
211             break;
212         }
213 
214         ret = HKS_SUCCESS;
215     } while (0);
216     mbedtls_sha1_free(context);
217     HKS_FREE(context);
218     ctx->append = NULL;
219     return ret;
220 }
221 
HksMbedtlsHashSha256Init(void ** ctx,int is224,uint32_t alg)222 static int32_t HksMbedtlsHashSha256Init(void **ctx, int is224, uint32_t alg)
223 {
224     mbedtls_sha256_context *context = (mbedtls_sha256_context *)HksMalloc(sizeof(mbedtls_sha256_context));
225     HKS_IF_NULL_LOGE_RETURN(context, HKS_ERROR_MALLOC_FAIL, "malloc fail")
226 
227     if (is224 != 0 && is224 != 1) {
228         HKS_LOG_E("Mbedtls Hash not sha224 & not sha256 ");
229         if (context != NULL) {
230             HKS_FREE(context);
231         }
232         return HKS_ERROR_INVALID_ARGUMENT;
233     }
234 
235     mbedtls_sha256_init(context);
236 
237     int32_t ret = mbedtls_sha256_starts_ret(context, is224);
238     if (ret != HKS_MBEDTLS_SUCCESS) {
239         HKS_LOG_E("Mbedtls Hash sha256 init fail");
240         mbedtls_sha256_free(context);
241         if (context != NULL) {
242             HKS_FREE(context);
243         }
244         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
245     }
246 
247     struct HksMbedtlsHashCtx *outCtx = (struct HksMbedtlsHashCtx *)HksMalloc(sizeof(HksMbedtlsHashCtx));
248     if (outCtx == NULL) {
249         HKS_LOG_E("Mbedtls Hash sha256 init fail_outCtx malloc fail");
250         mbedtls_sha256_free(context);
251         if (context != NULL) {
252             HKS_FREE(context);
253         }
254         return HKS_ERROR_MALLOC_FAIL;
255     }
256 
257     outCtx->append = (void *)context;
258     outCtx->mAlg = alg;
259     *ctx = (void *)outCtx;
260     return HKS_SUCCESS;
261 }
262 
HksMbedtlsHashSha256Update(struct HksMbedtlsHashCtx * ctx,const unsigned char * input,size_t ilen)263 static int32_t HksMbedtlsHashSha256Update(struct HksMbedtlsHashCtx *ctx, const unsigned char *input, size_t ilen)
264 {
265     mbedtls_sha256_context *context = (mbedtls_sha256_context *)ctx->append;
266     HKS_IF_NULL_RETURN(context, HKS_FAILURE)
267 
268     if (ilen == 0 || input == NULL) {
269         return HKS_FAILURE;
270     }
271 
272     int32_t ret = mbedtls_sha256_update_ret(context, input, ilen);
273     if (ret != HKS_MBEDTLS_SUCCESS) {
274         HKS_LOG_E("Mbedtls Hash sha256 update fail");
275         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
276     }
277 
278     return HKS_SUCCESS;
279 }
280 
HksMbedtlsHashSha256Final(struct HksMbedtlsHashCtx * ctx,const struct HksBlob * msg,struct HksBlob * hash)281 static int32_t HksMbedtlsHashSha256Final(struct HksMbedtlsHashCtx *ctx, const struct HksBlob *msg,
282     struct HksBlob *hash)
283 {
284     mbedtls_sha256_context *context = (mbedtls_sha256_context *)ctx->append;
285     HKS_IF_NULL_RETURN(context, HKS_ERROR_NULL_POINTER)
286 
287     int32_t ret = 0;
288     do {
289         if (hash->data == NULL) {
290             HKS_LOG_E("Mbedtls Hash sha256 output param error");
291             ret = HKS_ERROR_INVALID_ARGUMENT;
292             break;
293         }
294 
295         if (msg->size != 0) {
296             ret = mbedtls_sha256_update_ret(context, msg->data, msg->size);
297             if (ret != HKS_MBEDTLS_SUCCESS) {
298                 HKS_LOG_E("Mbedtls Hash sha256 update fail");
299                 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
300                 break;
301             }
302         }
303 
304         ret = mbedtls_sha256_finish_ret(context, hash->data);
305         if (ret != HKS_MBEDTLS_SUCCESS) {
306             HKS_LOG_E("Mbedtls Hash sha256 finish fail");
307             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
308             break;
309         }
310         ret = HKS_SUCCESS;
311     } while (0);
312 
313     mbedtls_sha256_free(context);
314     HKS_FREE(context);
315     ctx->append = NULL;
316 
317     return ret;
318 }
319 
HksMbedtlsHashSha512Init(void ** ctx,int is384,uint32_t alg)320 static int32_t HksMbedtlsHashSha512Init(void **ctx, int is384, uint32_t alg)
321 {
322     mbedtls_sha512_context *context = (mbedtls_sha512_context *)HksMalloc(sizeof(mbedtls_sha512_context));
323     HKS_IF_NULL_LOGE_RETURN(context, HKS_ERROR_MALLOC_FAIL, "malloc fail")
324 
325     if (is384 != 0 && is384 != 1) {
326         HKS_LOG_E("Mbedtls Hash not sha384 & not sha512 ");
327         if (context != NULL) {
328             HKS_FREE(context);
329         }
330         return HKS_ERROR_BAD_STATE;
331     }
332 
333     mbedtls_sha512_init(context);
334 
335     int32_t ret = mbedtls_sha512_starts_ret(context, is384);
336     if (ret != HKS_MBEDTLS_SUCCESS) {
337         HKS_LOG_E("Mbedtls Hash sha512 init fail");
338         mbedtls_sha512_free(context);
339         if (context != NULL) {
340             HKS_FREE(context);
341         }
342         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
343     }
344 
345     struct HksMbedtlsHashCtx *outCtx = (struct HksMbedtlsHashCtx *)HksMalloc(sizeof(HksMbedtlsHashCtx));
346     if (outCtx == NULL) {
347         HKS_LOG_E("Mbedtls Hash Md5 init fail_outCtx malloc fail");
348         mbedtls_sha512_free(context);
349         if (context != NULL) {
350             HKS_FREE(context);
351         }
352         return HKS_ERROR_MALLOC_FAIL;
353     }
354 
355     outCtx->append = (void *)context;
356     outCtx->mAlg = alg;
357     *ctx = (void *)outCtx;
358     return HKS_SUCCESS;
359 }
360 
HksMbedtlsHashSha512Update(struct HksMbedtlsHashCtx * ctx,const unsigned char * input,size_t ilen)361 static int32_t HksMbedtlsHashSha512Update(struct HksMbedtlsHashCtx *ctx, const unsigned char *input, size_t ilen)
362 {
363     mbedtls_sha512_context *context = (mbedtls_sha512_context *)ctx->append;
364     HKS_IF_NULL_RETURN(context, HKS_ERROR_NULL_POINTER)
365 
366     if (ilen == 0 || input == NULL) {
367         HKS_LOG_E("Mbedtls Hash sha512 input param error");
368         return HKS_ERROR_INVALID_ARGUMENT;
369     }
370 
371     int32_t ret = mbedtls_sha512_update_ret(context, input, ilen);
372     if (ret != HKS_MBEDTLS_SUCCESS) {
373         HKS_LOG_E("Mbedtls Hash sha512 update fail");
374         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
375     }
376 
377     return HKS_SUCCESS;
378 }
379 
HksMbedtlsHashSha512Final(struct HksMbedtlsHashCtx * ctx,const struct HksBlob * msg,struct HksBlob * hash)380 static int32_t HksMbedtlsHashSha512Final(struct HksMbedtlsHashCtx *ctx, const struct HksBlob *msg,
381     struct HksBlob *hash)
382 {
383     mbedtls_sha512_context *context = (mbedtls_sha512_context *)ctx->append;
384     HKS_IF_NULL_RETURN(context, HKS_ERROR_NULL_POINTER)
385 
386     int32_t ret = 0;
387     do {
388         if (hash->data == NULL) {
389             HKS_LOG_E("Mbedtls Hash sha512 output param error");
390             ret = HKS_ERROR_INVALID_ARGUMENT;
391             break;
392         }
393 
394         if (msg->size != 0) {
395             ret = mbedtls_sha512_update_ret(context, msg->data, msg->size);
396             if (ret != HKS_MBEDTLS_SUCCESS) {
397                 HKS_LOG_E("Mbedtls Hash sha512 finish last data fail");
398                 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
399                 break;
400             }
401         }
402 
403         ret = mbedtls_sha512_finish_ret(context, hash->data);
404         if (ret != HKS_MBEDTLS_SUCCESS) {
405             HKS_LOG_E("Mbedtls Hash sha512 finish fail");
406             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
407             break;
408         }
409 
410         ret = HKS_SUCCESS;
411     } while (0);
412 
413     mbedtls_sha512_free(context);
414     HKS_FREE(context);
415     ctx->append = NULL;
416     return ret;
417 }
418 
HksMbedtlsMd5HashFreeCtx(void ** cryptoCtx)419 static void HksMbedtlsMd5HashFreeCtx(void **cryptoCtx)
420 {
421     if (cryptoCtx == NULL || *cryptoCtx == NULL) {
422         HKS_LOG_E("Mbedtls Hash freeCtx param error");
423         return;
424     }
425     struct HksMbedtlsHashCtx *hashCtx = (struct HksMbedtlsHashCtx *)*cryptoCtx;
426     if (hashCtx->append != NULL) {
427         mbedtls_md5_free((mbedtls_md5_context *)hashCtx->append);
428     }
429 }
430 
HksMbedtlsSHA1HashFreeCtx(void ** cryptoCtx)431 static void HksMbedtlsSHA1HashFreeCtx(void **cryptoCtx)
432 {
433     if (cryptoCtx == NULL || *cryptoCtx == NULL) {
434         HKS_LOG_E("Mbedtls Hash freeCtx param error");
435         return;
436     }
437     struct HksMbedtlsHashCtx *hashCtx = (struct HksMbedtlsHashCtx *)*cryptoCtx;
438     if (hashCtx->append != NULL) {
439         mbedtls_sha1_free((mbedtls_sha1_context *)hashCtx->append);
440     }
441 }
442 
HksMbedtlsSha224Sha256HashFreeCtx(void ** cryptoCtx)443 static void HksMbedtlsSha224Sha256HashFreeCtx(void **cryptoCtx)
444 {
445     if (cryptoCtx == NULL || *cryptoCtx == NULL) {
446         HKS_LOG_E("Mbedtls Hash freeCtx param error");
447         return;
448     }
449     struct HksMbedtlsHashCtx *hashCtx = (struct HksMbedtlsHashCtx *)*cryptoCtx;
450     if (hashCtx->append != NULL) {
451         mbedtls_sha256_free((mbedtls_sha256_context *)hashCtx->append);
452     }
453 }
454 
HksMbedtlsSha384Sha512HashFreeCtx(void ** cryptoCtx)455 static void HksMbedtlsSha384Sha512HashFreeCtx(void **cryptoCtx)
456 {
457     if (cryptoCtx == NULL || *cryptoCtx == NULL) {
458         HKS_LOG_E("Mbedtls Hash freeCtx param error");
459         return;
460     }
461     struct HksMbedtlsHashCtx *hashCtx = (struct HksMbedtlsHashCtx *)*cryptoCtx;
462     if (hashCtx->append != NULL) {
463         mbedtls_sha512_free((mbedtls_sha512_context *)hashCtx->append);
464     }
465 }
466 
HksMbedtlsHashInit(void ** cryptoCtx,uint32_t digestAlg)467 int32_t HksMbedtlsHashInit(void **cryptoCtx, uint32_t digestAlg)
468 {
469     int32_t ret = 0;
470     switch (digestAlg) {
471         case HKS_DIGEST_MD5:
472             ret = HksMbedtlsHashMd5Init(cryptoCtx, digestAlg);
473             break;
474         case HKS_DIGEST_SHA1:
475             ret = HksMbedtlsHashSha1Init(cryptoCtx, digestAlg);
476             break;
477         case HKS_DIGEST_SHA224:
478             ret = HksMbedtlsHashSha256Init(cryptoCtx, 1, digestAlg); /* 0 for SHA-224 */
479             break;
480         case HKS_DIGEST_SHA256:
481             ret = HksMbedtlsHashSha256Init(cryptoCtx, 0, digestAlg); /* 0 for SHA-256 */
482             break;
483         case HKS_DIGEST_SHA384:
484             ret = HksMbedtlsHashSha512Init(cryptoCtx, 1, digestAlg); /* 1 for SHA-384 */
485             break;
486         case HKS_DIGEST_SHA512:
487             ret = HksMbedtlsHashSha512Init(cryptoCtx, 0, digestAlg); /* 0 for SHA-512 */
488             break;
489         default:
490             return HKS_ERROR_INVALID_DIGEST;
491     }
492 
493     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Mbedtls hash init failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret)
494 
495     return HKS_SUCCESS;
496 }
497 
HksMbedtlsHashUpdate(void * cryptoCtx,const struct HksBlob * msg)498 int32_t HksMbedtlsHashUpdate(void *cryptoCtx, const struct HksBlob *msg)
499 {
500     int32_t ret = 0;
501     struct HksMbedtlsHashCtx *hashCtx = (struct HksMbedtlsHashCtx *)cryptoCtx;
502 
503     switch (hashCtx->mAlg) {
504         case HKS_DIGEST_MD5:
505             ret = HksMbedtlsHashMd5Update(hashCtx, msg->data, msg->size);
506             break;
507         case HKS_DIGEST_SHA1:
508             ret = HksMbedtlsHashSha1Update(hashCtx, msg->data, msg->size);
509             break;
510         case HKS_DIGEST_SHA224:
511         case HKS_DIGEST_SHA256:
512             ret = HksMbedtlsHashSha256Update(hashCtx, msg->data, msg->size);
513             break;
514         case HKS_DIGEST_SHA384:
515         case HKS_DIGEST_SHA512:
516             ret = HksMbedtlsHashSha512Update(hashCtx, msg->data, msg->size);
517             break;
518         default:
519             return HKS_ERROR_INVALID_DIGEST;
520     }
521 
522     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Mbedtls hash update failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret)
523 
524     return HKS_SUCCESS;
525 }
526 
HksMbedtlsHashFinal(void ** cryptoCtx,const struct HksBlob * msg,struct HksBlob * hash)527 int32_t HksMbedtlsHashFinal(void **cryptoCtx, const struct HksBlob *msg, struct HksBlob *hash)
528 {
529     int32_t ret = 0;
530     struct HksMbedtlsHashCtx *hashCtx = (struct HksMbedtlsHashCtx *)*cryptoCtx;
531     HKS_IF_NULL_RETURN(hashCtx, HKS_ERROR_INVALID_ARGUMENT)
532 
533     switch (hashCtx->mAlg) {
534         case HKS_DIGEST_MD5:
535             ret = HksMbedtlsHashMd5Final(hashCtx, msg, hash);
536             break;
537         case HKS_DIGEST_SHA1:
538             ret = HksMbedtlsHashSha1Final(hashCtx, msg, hash);
539             break;
540         case HKS_DIGEST_SHA224:
541         case HKS_DIGEST_SHA256:
542             ret = HksMbedtlsHashSha256Final(hashCtx, msg, hash);
543             break;
544         case HKS_DIGEST_SHA384:
545         case HKS_DIGEST_SHA512:
546             ret = HksMbedtlsHashSha512Final(hashCtx, msg, hash);
547             break;
548         default:
549             HksMbedtlsHashFreeCtx(cryptoCtx);
550             return HKS_ERROR_INVALID_DIGEST;
551     }
552 
553     if (ret != HKS_SUCCESS) {
554         HKS_LOG_E("Mbedtls hash final failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
555         HKS_FREE(*cryptoCtx);
556         *cryptoCtx = NULL;
557         return ret;
558     }
559 
560     ret = HksGetDigestLen(hashCtx->mAlg, &(hash->size));
561     HKS_IF_NOT_SUCC_LOGE(ret, "Get digest len failed!")
562 
563     HksMbedtlsHashFreeCtx(cryptoCtx);
564     return ret;
565 }
566 
HksMbedtlsHashFreeCtx(void ** cryptoCtx)567 void HksMbedtlsHashFreeCtx(void **cryptoCtx)
568 {
569     if (cryptoCtx == NULL || *cryptoCtx == NULL) {
570         HKS_LOG_E("Mbedtls Hash freeCtx param error");
571         return;
572     }
573     struct HksMbedtlsHashCtx *hashCtx = (struct HksMbedtlsHashCtx *)*cryptoCtx;
574     switch (hashCtx->mAlg) {
575         case HKS_DIGEST_MD5:
576             HksMbedtlsMd5HashFreeCtx(cryptoCtx);
577             break;
578         case HKS_DIGEST_SHA1:
579             HksMbedtlsSHA1HashFreeCtx(cryptoCtx);
580             break;
581         case HKS_DIGEST_SHA224:
582         case HKS_DIGEST_SHA256:
583             HksMbedtlsSha224Sha256HashFreeCtx(cryptoCtx);
584             break;
585         case HKS_DIGEST_SHA384:
586         case HKS_DIGEST_SHA512:
587             HksMbedtlsSha384Sha512HashFreeCtx(cryptoCtx);
588             break;
589         default:
590             break;
591     }
592 
593     if (*cryptoCtx != NULL) {
594         if (hashCtx->append != NULL) {
595             HKS_FREE(hashCtx->append);
596             hashCtx->append = NULL;
597         }
598 
599         HKS_FREE(*cryptoCtx);
600         *cryptoCtx = NULL;
601     }
602 }
603 
HksMbedtlsHash(uint32_t alg,const struct HksBlob * msg,struct HksBlob * hash)604 int32_t HksMbedtlsHash(uint32_t alg, const struct HksBlob *msg, struct HksBlob *hash)
605 {
606     int32_t ret = 0;
607     switch (alg) {
608 #ifdef HKS_SUPPORT_HASH_MD5
609         case HKS_DIGEST_MD5:
610             ret = mbedtls_md5_ret(msg->data, msg->size, hash->data);
611             break;
612 #endif
613 #ifdef HKS_SUPPORT_HASH_SHA1
614         case HKS_DIGEST_SHA1:
615             ret = mbedtls_sha1_ret(msg->data, msg->size, hash->data);
616             break;
617 #endif
618 #ifdef HKS_SUPPORT_HASH_SHA224
619         case HKS_DIGEST_SHA224:
620             ret = mbedtls_sha256_ret(msg->data, msg->size, hash->data, 1); /* 0 for SHA-224 */
621             break;
622 #endif
623 #ifdef HKS_SUPPORT_HASH_SHA256
624         case HKS_DIGEST_SHA256:
625             ret = mbedtls_sha256_ret(msg->data, msg->size, hash->data, 0); /* 0 for SHA-256 */
626             break;
627 #endif
628 #ifdef HKS_SUPPORT_HASH_SHA384
629         case HKS_DIGEST_SHA384:
630             ret = mbedtls_sha512_ret(msg->data, msg->size, hash->data, 1); /* 1 for SHA-384 */
631             break;
632 #endif
633 #ifdef HKS_SUPPORT_HASH_SHA512
634         case HKS_DIGEST_SHA512:
635             ret = mbedtls_sha512_ret(msg->data, msg->size, hash->data, 0); /* 0 for SHA-512 */
636             break;
637 #endif
638         default:
639             return HKS_ERROR_INVALID_DIGEST;
640     }
641 
642     if (ret != HKS_MBEDTLS_SUCCESS) {
643         HKS_LOG_E("Mbedtls hash failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
644         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
645     }
646 
647     ret = HksGetDigestLen(alg, &(hash->size));
648     HKS_IF_NOT_SUCC_LOGE(ret, "Get digest len failed!")
649 
650     return ret;
651 }
652 #endif /* HKS_SUPPORT_HASH_C */
653