• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include "cryp_hash.h"
20 #include "drv_osal_lib.h"
21 #include "securec.h"
22 
23 #ifdef MHASH_NONSUPPORT
24 #define HASH_SOFT_CHANNEL_MAX             0x01
25 #define HASH_SOFT_CHANNEL_MASK            0x01
26 #else
27 #define HASH_SOFT_CHANNEL_MAX             0x08
28 #define HASH_SOFT_CHANNEL_MASK            0xFF
29 #endif
30 
31 /* hmac ipad byte */
32 #define HMAC_IPAD_BYTE                    0x36
33 
34 /* hmac opad byte */
35 #define HMAC_OPAD_BYTE                    0x5C
36 
37 #define HMAC_HASH                         0x01
38 #define HMAC_AESCBC                       0x02
39 
40 typedef struct {
41     hash_func *func;                      /* HASH function */
42     hi_void *cryp_ctx;                    /* Context of cryp instance */
43     hi_u32 hmac;                          /* HMAC or not */
44     hi_u32 mac_id;                        /* CMAC handle */
45     hi_u8 hmac_ipad[HASH_BLOCK_SIZE_128]; /* hmac ipad */
46     hi_u8 hmac_opad[HASH_BLOCK_SIZE_128]; /* hmac opad */
47     CRYPTO_OWNER owner;                   /* user ID */
48 } kapi_hash_ctx;
49 
50 /* Context of cipher */
51 static channel_context g_hash_ctx[HASH_SOFT_CHANNEL_MAX];
52 
53 /* hash mutex */
54 static CRYPTO_MUTEX g_hash_mutex;
55 
56 #define kapi_hash_lock_err_return()   \
57     do { \
58         ret = crypto_mutex_lock(&g_hash_mutex);  \
59         if (ret != HI_SUCCESS) { \
60             hi_log_error("error, hash lock failed\n"); \
61             hi_log_print_err_code(HI_ERR_CIPHER_BUSY); \
62             return HI_ERR_CIPHER_BUSY; \
63         } \
64     } while (0)
65 
66 #define kapi_hash_unlock()   crypto_mutex_unlock(&g_hash_mutex)
67 
kapi_hash_chk_handle(hi_handle handle)68 static hi_s32 kapi_hash_chk_handle(hi_handle handle)
69 {
70     if ((hi_handle_get_modid(handle) != HI_ID_CIPHER) || (hi_handle_get_private_data(handle) != 0)) {
71         hi_log_error("invalid handle 0x%x!\n", handle);
72         hi_log_print_err_code(HI_ERR_CIPHER_INVALID_HANDLE);
73         return HI_ERR_CIPHER_INVALID_HANDLE;
74     }
75 
76     if (hi_handle_get_chnid(handle) >= HASH_SOFT_CHANNEL_MAX) {
77         hi_log_error("chan %u is too large, max: %d\n", hi_handle_get_chnid(handle), HASH_SOFT_CHANNEL_MAX);
78         hi_log_print_err_code(HI_ERR_CIPHER_INVALID_HANDLE);
79         return HI_ERR_CIPHER_INVALID_HANDLE;
80     }
81 
82     if (g_hash_ctx[hi_handle_get_chnid(handle)].open == HI_FALSE) {
83         hi_log_error("chan %u is not open\n", hi_handle_get_chnid(handle));
84         hi_log_print_err_code(HI_ERR_CIPHER_INVALID_HANDLE);
85         return HI_ERR_CIPHER_INVALID_HANDLE;
86     }
87 
88     return HI_SUCCESS;
89 }
90 
91 /* API Code for kapi hash. */
kapi_hash_init(hi_void)92 hi_s32 kapi_hash_init(hi_void)
93 {
94     hi_s32 ret;
95 
96     hi_log_func_enter();
97 
98     hi_log_info("HASH init\n");
99 
100     crypto_mutex_init(&g_hash_mutex);
101 
102     ret = cryp_hash_init();
103     if (ret != HI_SUCCESS) {
104         hi_log_print_func_err(cryp_hash_init, ret);
105         return ret;
106     }
107 
108     /* Initialize soft channel list */
109     ret = crypto_channel_init(g_hash_ctx, HASH_SOFT_CHANNEL_MAX, sizeof(kapi_hash_ctx));
110     if (ret != HI_SUCCESS) {
111         hi_log_print_func_err(crypto_channel_init, ret);
112         cryp_hash_deinit();
113         return ret;
114     }
115 
116     hi_log_func_exit();
117     return HI_SUCCESS;
118 }
119 
kapi_hash_deinit(hi_void)120 hi_s32 kapi_hash_deinit(hi_void)
121 {
122     hi_s32 ret;
123 
124     hi_log_func_enter();
125 
126     ret = crypto_channel_deinit(g_hash_ctx, HASH_SOFT_CHANNEL_MAX);
127     if (ret != HI_SUCCESS) {
128         hi_log_print_func_err(crypto_channel_deinit, ret);
129         return ret;
130     }
131 
132     cryp_hash_deinit();
133 
134     crypto_mutex_destroy(&g_hash_mutex);
135 
136     hi_log_func_exit();
137     return HI_SUCCESS;
138 }
139 
kapi_hash_get_ctx(hi_u32 id)140 static kapi_hash_ctx *kapi_hash_get_ctx(hi_u32 id)
141 {
142     return crypto_channel_get_context(g_hash_ctx, HASH_SOFT_CHANNEL_MAX, id);
143 }
144 
kapi_hash_create(hi_u32 * id)145 static hi_s32 kapi_hash_create(hi_u32 *id)
146 {
147     hi_s32 ret;
148     hi_u32 chn = 0;
149 
150     hi_log_func_enter();
151 
152     /* allocate a hash channel */
153     ret = crypto_channel_alloc(g_hash_ctx, HASH_SOFT_CHANNEL_MAX, HASH_SOFT_CHANNEL_MASK, &chn);
154     if (ret != HI_SUCCESS) {
155         hi_log_print_func_err(crypto_channel_alloc, ret);
156         return ret;
157     }
158 
159     *id = chn;
160 
161     hi_log_debug("kapi create soft chn %u\n", chn);
162 
163     hi_log_func_exit();
164     return HI_SUCCESS;
165 }
166 
kapi_hash_destroy(hi_u32 id)167 static hi_s32 kapi_hash_destroy(hi_u32 id)
168 {
169     hi_log_func_enter();
170 
171     hi_log_chk_param_return(id >= HASH_SOFT_CHANNEL_MAX);
172 
173     /* Free soft channel */
174     crypto_channel_free(g_hash_ctx, HASH_SOFT_CHANNEL_MAX, id);
175 
176     hi_log_func_exit();
177     return HI_SUCCESS;
178 }
179 
kpai_hash_mode_transform(hi_cipher_hash_type type,hash_mode * mode,hi_u32 * hmac)180 static hi_s32 kpai_hash_mode_transform(hi_cipher_hash_type type, hash_mode *mode, hi_u32 *hmac)
181 {
182     *hmac = HI_FALSE;
183 
184     /* transform hash mode */
185     switch (type) {
186         case HI_CIPHER_HASH_TYPE_HMAC_SHA1:
187             *hmac = HMAC_HASH;
188             *mode = HASH_MODE_SHA1;
189             break;
190         case HI_CIPHER_HASH_TYPE_SHA1:
191             *mode = HASH_MODE_SHA1;
192             break;
193         case HI_CIPHER_HASH_TYPE_HMAC_SHA224:
194             *hmac = HMAC_HASH;
195             *mode = HASH_MODE_SHA224;
196             break;
197         case HI_CIPHER_HASH_TYPE_SHA224:
198             *mode = HASH_MODE_SHA224;
199             break;
200         case HI_CIPHER_HASH_TYPE_HMAC_SHA256:
201             *hmac = HMAC_HASH;
202             *mode = HASH_MODE_SHA256;
203             break;
204         case HI_CIPHER_HASH_TYPE_SHA256:
205             *mode = HASH_MODE_SHA256;
206             break;
207         case HI_CIPHER_HASH_TYPE_HMAC_SHA384:
208             *hmac = HMAC_HASH;
209             *mode = HASH_MODE_SHA384;
210             break;
211         case HI_CIPHER_HASH_TYPE_SHA384:
212             *mode = HASH_MODE_SHA384;
213             break;
214         case HI_CIPHER_HASH_TYPE_HMAC_SHA512:
215             *hmac = HMAC_HASH;
216             *mode = HASH_MODE_SHA512;
217             break;
218         case HI_CIPHER_HASH_TYPE_SHA512:
219             *mode = HASH_MODE_SHA512;
220             break;
221         case HI_CIPHER_HASH_TYPE_SM3:
222             *mode = HASH_MODE_SM3;
223             break;
224         default:
225             hi_log_error("error, invalid hash type %d\n", type);
226             hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARAM);
227             return HI_ERR_CIPHER_INVALID_PARAM;
228     }
229     return HI_SUCCESS;
230 }
231 
kapi_hmac_cal_ipad_opad(kapi_hash_ctx * ctx)232 static hi_void kapi_hmac_cal_ipad_opad(kapi_hash_ctx *ctx)
233 {
234     hi_u32 i;
235 
236     for (i = 0; i < ctx->func->block_size; i++) {
237         ctx->hmac_ipad[i] ^= HMAC_IPAD_BYTE;
238         ctx->hmac_opad[i] ^= HMAC_OPAD_BYTE;
239     }
240 }
241 
kapi_hmac_start(kapi_hash_ctx * ctx,const hi_u8 * key,hi_u32 keylen)242 static hi_s32 kapi_hmac_start(kapi_hash_ctx *ctx, const hi_u8 *key, hi_u32 keylen)
243 {
244     hi_s32 ret;
245     hi_u8 sum[HASH_RESULT_MAX_SIZE] = {0};
246     hi_u32 len = 0;
247 
248     hi_log_func_enter();
249 
250     hi_log_chk_param_return(key == HI_NULL);
251 
252     /* clean ipad and opad */
253     if ((memset_s(ctx->hmac_ipad, HASH_BLOCK_SIZE_128, 0x00, ctx->func->block_size) != EOK) ||
254         (memset_s(ctx->hmac_opad, HASH_BLOCK_SIZE_128, 0x00, ctx->func->block_size) != EOK)) {
255         hi_log_print_func_err(memset_s, HI_ERR_CIPHER_MEMSET_S_FAILED);
256         return HI_ERR_CIPHER_MEMSET_S_FAILED;
257     }
258 
259     /* compute K0 */
260     if (keylen <= ctx->func->block_size) {
261         /* If the length of K = B: set K0 = K.
262          *
263          * If the length of K > B: hash K to obtain an L byte string,
264          * then append (B-L) zeros to create a B-byte
265          * string K0 (i.e., K0 = H(K) || 00...00).
266          */
267         if ((memcpy_s(ctx->hmac_ipad, HASH_BLOCK_SIZE_128, key, keylen) != EOK) ||
268             (memcpy_s(ctx->hmac_opad, HASH_BLOCK_SIZE_128, key, keylen) != EOK)) {
269             return HI_ERR_CIPHER_MEMCPY_S_FAILED;
270         }
271     } else {
272         /* If the length of K > B: hash K to obtain an L byte string,
273          * then append (B-L) zeros to create a B-byte
274          * string K0 (i.e., K0 = H(K) || 00...00).
275          */
276         ctx->cryp_ctx = ctx->func->create(ctx->func->mode); /* H(K) */
277         if (ctx->cryp_ctx == HI_NULL) {
278             hi_log_print_func_err(ctx->func->create, HI_ERR_CIPHER_BUSY);
279             return HI_ERR_CIPHER_BUSY;
280         }
281 
282         /* update key */
283         crypto_chk_err_goto(ctx->func->update(ctx->cryp_ctx, key, keylen, HASH_CHUNCK_SRC_LOCAL));
284 
285         /* sum */
286         crypto_chk_err_goto(ctx->func->finish(ctx->cryp_ctx, sum, sizeof(sum), &len));
287         ctx->func->destroy(ctx->cryp_ctx);
288         ctx->cryp_ctx = HI_NULL;
289 
290         /* descript: K0 = H(K) || 00...00. */
291         if ((memcpy_s(ctx->hmac_ipad, sizeof(ctx->hmac_ipad), sum, len) != EOK) ||
292             (memcpy_s(ctx->hmac_opad, sizeof(ctx->hmac_opad), sum, len) != EOK)) {
293             ret = HI_ERR_CIPHER_MEMCPY_S_FAILED;
294             goto exit__;
295         }
296     }
297 
298     /* Exclusive-Or K0 with ipad/opad byte to produce K0 ^ ipad and K0 ^ opad */
299     kapi_hmac_cal_ipad_opad(ctx);
300 
301     /* H(K0 ^ ipad) */
302     ctx->cryp_ctx = ctx->func->create(ctx->func->mode);
303     if (ctx->cryp_ctx == HI_NULL) {
304         hi_log_print_func_err(ctx->func->create, HI_ERR_CIPHER_BUSY);
305         return HI_ERR_CIPHER_BUSY;
306     }
307     crypto_chk_err_goto(ctx->func->update(ctx->cryp_ctx, ctx->hmac_ipad, ctx->func->block_size, HASH_CHUNCK_SRC_LOCAL));
308 
309     hi_log_func_exit();
310     return HI_SUCCESS;
311 
312 exit__:
313     ctx->func->destroy(ctx->cryp_ctx);
314     ctx->cryp_ctx = HI_NULL;
315     (hi_void)memset_s(ctx->hmac_ipad, sizeof(ctx->hmac_ipad), 0, sizeof(ctx->hmac_ipad));
316     (hi_void)memset_s(ctx->hmac_opad, sizeof(ctx->hmac_opad), 0, sizeof(ctx->hmac_opad));
317     return ret;
318 }
319 
kapi_hmac_finish(kapi_hash_ctx * ctx,hi_u8 * hash,hi_u32 hash_buf_len,hi_u32 * hashlen)320 static hi_s32 kapi_hmac_finish(kapi_hash_ctx *ctx, hi_u8 *hash, hi_u32 hash_buf_len, hi_u32 *hashlen)
321 {
322     hi_s32 ret;
323     hi_u8 sum[HASH_RESULT_MAX_SIZE] = {0};
324 
325     hi_log_func_enter();
326 
327     /* descript: sum = H((K0 ^ ipad) || text). */
328     ctx->func->finish(ctx->cryp_ctx, sum, sizeof(sum), hashlen);
329     ctx->func->destroy(ctx->cryp_ctx);
330     ctx->cryp_ctx = HI_NULL;
331 
332     /* H((K0 ^ opad)|| sum). */
333     ctx->cryp_ctx = ctx->func->create(ctx->func->mode);
334     if (ctx->cryp_ctx == HI_NULL) {
335         hi_log_print_func_err(ctx->func->create, 0);
336         return HI_ERR_CIPHER_BUSY;
337     }
338 
339     /* update(K0 ^ opad) */
340     ret = ctx->func->update(ctx->cryp_ctx, ctx->hmac_opad, ctx->func->block_size, HASH_CHUNCK_SRC_LOCAL);
341     if (ret != HI_SUCCESS) {
342         hi_log_print_func_err(ctx->func->update, ret);
343         return ret;
344     }
345 
346     /* update(sum) */
347     ret = ctx->func->update(ctx->cryp_ctx, sum, ctx->func->size, HASH_CHUNCK_SRC_LOCAL);
348     if (ret != HI_SUCCESS) {
349         hi_log_print_func_err(ctx->func->update, ret);
350         return ret;
351     }
352 
353     /* H */
354     ret = ctx->func->finish(ctx->cryp_ctx, hash, hash_buf_len, hashlen);
355     if (ret != HI_SUCCESS) {
356         hi_log_print_func_err(ctx->func->finish, ret);
357         return ret;
358     }
359 
360     hi_log_func_exit();
361     return HI_SUCCESS;
362 }
363 
kapi_hash_finsh_calc(kapi_hash_ctx * ctx,hi_u8 * hash,hi_u32 hash_buf_len,hi_u32 * hashlen)364 static hi_s32 kapi_hash_finsh_calc(kapi_hash_ctx *ctx, hi_u8 *hash, hi_u32 hash_buf_len, hi_u32 *hashlen)
365 {
366     hi_s32 ret;
367 
368     if (ctx->hmac) {
369         ret = kapi_hmac_finish(ctx, hash, hash_buf_len, hashlen);
370         if (ret != HI_SUCCESS) {
371             hi_log_print_func_err(kapi_hmac_finish, ret);
372             return ret;
373         }
374     } else {
375         ret = ctx->func->finish(ctx->cryp_ctx, hash, hash_buf_len, hashlen);
376         if (ret != HI_SUCCESS) {
377             hi_log_print_func_err(ctx->func->finish, ret);
378             return ret;
379         }
380     }
381 
382     return HI_SUCCESS;
383 }
384 
kapi_hash_chk_ctx(hi_u32 id,hi_u32 * soft_hash_id)385 static hi_s32 kapi_hash_chk_ctx(hi_u32 id, hi_u32 *soft_hash_id)
386 {
387     hi_s32 ret;
388     kapi_hash_ctx *ctx = HI_NULL;
389 
390     ret = kapi_hash_chk_handle((hi_handle)id);
391     if (ret != HI_SUCCESS) {
392         hi_log_print_func_err(kapi_hash_chk_handle, ret);
393         return ret;
394     }
395 
396     *soft_hash_id = hi_handle_get_chnid(id);
397     ctx = kapi_hash_get_ctx(*soft_hash_id);
398     if (ctx == HI_NULL) {
399         hi_log_error("kapi hash get ctx is null.\n");
400         hi_log_print_func_err(kapi_hash_get_ctx, HI_ERR_CIPHER_INVALID_POINT);
401         return HI_ERR_CIPHER_INVALID_POINT;
402     }
403 
404     crypto_chk_owner_err_return(&ctx->owner);
405     return HI_SUCCESS;
406 }
407 
kapi_hash_set_ctx(kapi_hash_ctx * ctx,hash_mode mode,hi_u32 hmac)408 static hi_s32 kapi_hash_set_ctx(kapi_hash_ctx *ctx, hash_mode mode, hi_u32 hmac)
409 {
410     (hi_void)memset_s(ctx, sizeof(kapi_hash_ctx), 0, sizeof(kapi_hash_ctx));
411     /* record owner */
412     crypto_get_owner(&ctx->owner);
413     ctx->hmac = hmac;
414 
415     /* Clone the function from template of hash engine */
416     ctx->cryp_ctx = HI_NULL;
417     ctx->func = cryp_get_hash(mode);
418     if (ctx->func == HI_NULL) {
419         hi_log_print_func_err(cryp_get_hash, HI_ERR_CIPHER_INVALID_PARAM);
420         return HI_ERR_CIPHER_INVALID_PARAM;
421     }
422 
423     if ((ctx->func->create == HI_NULL) || (ctx->func->update == HI_NULL) ||
424         (ctx->func->finish == HI_NULL) || (ctx->func->destroy == HI_NULL)) {
425         hi_log_error("error, cryp hash func is null.\n");
426         hi_log_print_err_code(HI_ERR_CIPHER_UNSUPPORTED);
427         return HI_ERR_CIPHER_UNSUPPORTED;
428     }
429 
430     return HI_SUCCESS;
431 }
432 
kapi_hash_create_calc(kapi_hash_ctx * ctx,hash_mode mode,hi_u32 hmac,const hi_u8 * key,hi_u32 keylen)433 static hi_s32 kapi_hash_create_calc(kapi_hash_ctx *ctx,
434     hash_mode mode, hi_u32 hmac, const hi_u8 *key, hi_u32 keylen)
435 {
436     hi_s32 ret;
437 
438     ret = kapi_hash_set_ctx(ctx, mode, hmac);
439     if (ret != HI_SUCCESS) {
440         hi_log_print_func_err(kapi_hash_set_ctx, ret);
441         return ret;
442     }
443 
444     if (ctx->hmac) {
445         ret = kapi_hmac_start(ctx, key, keylen);
446         if (ret != HI_SUCCESS) {
447             hi_log_print_func_err(kapi_hmac_start, ret);
448             return ret;
449         }
450     } else {
451         ctx->cryp_ctx = ctx->func->create(mode);
452         if (ctx->cryp_ctx == HI_NULL) {
453             hi_log_print_func_err(ctx->func->create, HI_ERR_CIPHER_FAILED_MEM);
454             return HI_ERR_CIPHER_FAILED_MEM;
455         }
456     }
457     return HI_SUCCESS;
458 }
459 
kapi_hash_chk_type(hi_cipher_hash_type type)460 static hi_s32 kapi_hash_chk_type(hi_cipher_hash_type type)
461 {
462 #ifndef CHIP_SHA1_SUPPORT
463     if (type == HI_CIPHER_HASH_TYPE_SHA1 || type == HI_CIPHER_HASH_TYPE_HMAC_SHA1) {
464         hi_log_error("Invalid alg, unsupported sha1.\n");
465         hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARA);
466         return HI_ERR_CIPHER_INVALID_PARA;
467     }
468 #endif
469 
470 #ifndef CHIP_SHA224_SUPPORT
471     if (type == HI_CIPHER_HASH_TYPE_SHA224 || type == HI_CIPHER_HASH_TYPE_HMAC_SHA224) {
472         hi_log_error("Invalid alg, unsupported sha224.\n");
473         hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARA);
474         return HI_ERR_CIPHER_INVALID_PARA;
475     }
476 #endif
477 
478     crypto_unused(type);
479     return HI_SUCCESS;
480 }
481 
kapi_hash_start(hi_u32 * id,hi_cipher_hash_type type,const hi_u8 * key,hi_u32 keylen)482 hi_s32 kapi_hash_start(hi_u32 *id, hi_cipher_hash_type type, const hi_u8 *key, hi_u32 keylen)
483 {
484     hi_s32 ret, ret_error;
485     kapi_hash_ctx *ctx = HI_NULL;
486     hash_mode mode = 0x00;
487     hi_u32 hmac = 0;
488     hi_u32 soft_hash_id = 0;
489 
490     hi_log_func_enter();
491 
492     hi_log_chk_param_return(id == HI_NULL);
493 
494     ret = kapi_hash_chk_type(type);
495     if (ret != HI_SUCCESS) {
496         return ret;
497     }
498 
499     /* transform hash mode */
500     ret = kpai_hash_mode_transform(type, &mode, &hmac);
501     if (ret != HI_SUCCESS) {
502         hi_log_print_func_err(kpai_hash_mode_transform, ret);
503         return ret;
504     }
505 
506     kapi_hash_lock_err_return();
507 
508     /* Create hash channel */
509     ret = kapi_hash_create(&soft_hash_id);
510     if (ret != HI_SUCCESS) {
511         hi_log_print_func_err(kapi_hash_create, ret);
512         kapi_hash_unlock();
513         return ret;
514     }
515 
516     ctx = kapi_hash_get_ctx(soft_hash_id);
517     if (ctx == HI_NULL) {
518         hi_log_print_func_err(kapi_hash_get_ctx, HI_ERR_CIPHER_FAILED_MEM);
519         ret = HI_ERR_CIPHER_FAILED_MEM;
520         goto error1;
521     }
522 
523     ret = kapi_hash_create_calc(ctx, mode, hmac, key, keylen);
524     if (ret != HI_SUCCESS) {
525         hi_log_print_func_err(kapi_hash_create_calc, ret);
526         goto error1;
527     }
528 
529     *id = hi_handle_init(HI_ID_CIPHER, 0, soft_hash_id);
530     kapi_hash_unlock();
531     hi_log_func_exit();
532     return HI_SUCCESS;
533 
534 error1:
535     ret_error = kapi_hash_destroy(soft_hash_id);
536     if (ret_error != HI_SUCCESS) {
537         hi_log_print_func_err(kapi_hash_destroy, ret_error);
538     }
539 
540     kapi_hash_unlock();
541     hi_log_func_exit();
542     return ret;
543 }
544 
kapi_hash_update(hi_u32 id,const hi_u8 * input,hi_u32 length,hash_chunk_src src)545 hi_s32 kapi_hash_update(hi_u32 id, const hi_u8 *input, hi_u32 length, hash_chunk_src src)
546 {
547     hi_s32 ret;
548     kapi_hash_ctx *ctx = HI_NULL;
549     hi_u32 soft_hash_id = 0;
550 
551     hi_log_func_enter();
552 
553     hi_log_chk_param_return(input > input + length); /* check overflow */
554     ret = kapi_hash_chk_ctx((hi_handle)id, &soft_hash_id);
555     if (ret != HI_SUCCESS) {
556         hi_log_print_func_err(kapi_hash_chk_ctx, ret);
557         return ret;
558     }
559 
560     ctx = kapi_hash_get_ctx(soft_hash_id);
561     hi_log_chk_param_return(ctx == HI_NULL);
562     hi_log_chk_param_return(ctx->cryp_ctx == HI_NULL);
563     hi_log_chk_param_return(ctx->func == HI_NULL);
564     hi_log_chk_param_return(ctx->func->update == HI_NULL);
565 
566     kapi_hash_lock_err_return();
567 
568     ret = ctx->func->update(ctx->cryp_ctx, input, length, src);
569     /* release resource */
570     if (ret != HI_SUCCESS) {
571         ctx->func->destroy(ctx->cryp_ctx);
572         ctx->cryp_ctx = HI_NULL;
573         kapi_hash_destroy(soft_hash_id);
574         hi_log_print_func_err(ctx->func->update, ret);
575         kapi_hash_unlock();
576         return ret;
577     }
578 
579     kapi_hash_unlock();
580 
581     hi_log_func_exit();
582 
583     return HI_SUCCESS;
584 }
585 
kapi_hash_finish(hi_u32 id,hi_u8 * hash,hi_u32 hash_buf_len,hi_u32 * hashlen)586 hi_s32 kapi_hash_finish(hi_u32 id, hi_u8 *hash, hi_u32 hash_buf_len, hi_u32 *hashlen)
587 {
588     hi_s32 ret;
589     kapi_hash_ctx *ctx = HI_NULL;
590     hi_u32 soft_hash_id = 0;
591 
592     hi_log_func_enter();
593 
594     hi_log_chk_param_return(hash == HI_NULL);
595     hi_log_chk_param_return(hash_buf_len == 0);
596     hi_log_chk_param_return(hashlen == HI_NULL);
597 
598     ret = kapi_hash_chk_ctx((hi_handle)id, &soft_hash_id);
599     if (ret != HI_SUCCESS) {
600         hi_log_print_func_err(kapi_hash_chk_ctx, ret);
601         return ret;
602     }
603 
604     ctx = kapi_hash_get_ctx(soft_hash_id);
605     hi_log_chk_param_return(ctx == HI_NULL);
606     hi_log_chk_param_return(ctx->cryp_ctx == HI_NULL);
607     hi_log_chk_param_return(ctx->func == HI_NULL);
608     hi_log_chk_param_return(ctx->func->destroy == HI_NULL);
609 
610     kapi_hash_lock_err_return();
611 
612     ret = kapi_hash_finsh_calc(ctx, hash, hash_buf_len, hashlen);
613     if (ret != HI_SUCCESS) {
614         hi_log_print_func_err(kapi_hash_finsh_calc, ret);
615         ctx->func->destroy(ctx->cryp_ctx);
616         ctx->cryp_ctx = HI_NULL;
617         (hi_void)kapi_hash_destroy(soft_hash_id);
618         kapi_hash_unlock();
619         return ret;
620     }
621 
622     /* release resource */
623     ctx->func->destroy(ctx->cryp_ctx);
624     ctx->cryp_ctx = HI_NULL;
625     ret = kapi_hash_destroy(soft_hash_id);
626     if (ret != HI_SUCCESS) {
627         hi_log_print_func_err(kapi_hash_destroy, ret);
628         kapi_hash_unlock();
629         return ret;
630     }
631 
632     kapi_hash_unlock();
633     hi_log_func_exit();
634     return HI_SUCCESS;
635 }
636 
kapi_hash_release(hi_void)637 hi_s32 kapi_hash_release(hi_void)
638 {
639     hi_u32 i;
640     hi_s32 ret;
641     kapi_hash_ctx *ctx = HI_NULL;
642     CRYPTO_OWNER owner;
643 
644     hi_log_func_enter();
645 
646     crypto_get_owner(&owner);
647 
648     hi_log_info("hash release owner 0x%x\n", owner);
649 
650     /* destroy the channel which are created by current user */
651     for (i = 0; i < HASH_SOFT_CHANNEL_MAX; i++) {
652         if (g_hash_ctx[i].open == HI_TRUE) {
653             ctx = kapi_hash_get_ctx(i);
654             if (ctx == HI_NULL) {
655                 hi_log_error("kapi hash get ctx failed, point is null.\n");
656                 hi_log_print_err_code(HI_ERR_CIPHER_INVALID_POINT);
657                 return HI_ERR_CIPHER_INVALID_POINT;
658             }
659             if (memcmp(&owner, &ctx->owner, sizeof(owner)) != 0) {
660                 continue;
661             }
662 
663             hi_log_info("hash release chn %u\n", i);
664             if ((ctx->func != HI_NULL) && (ctx->func->destroy != HI_NULL) && (ctx->cryp_ctx != HI_NULL)) {
665                 ctx->func->destroy(ctx->cryp_ctx);
666             }
667             ctx->cryp_ctx = HI_NULL;
668             ret = kapi_hash_destroy(i);
669             if (ret != HI_SUCCESS) {
670                 hi_log_print_func_err(kapi_hash_destroy, ret);
671                 return ret;
672             }
673         }
674     }
675 
676     hi_log_func_exit();
677     return HI_SUCCESS;
678 }
679