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