• 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 "drv_osal_lib.h"
20 #include "drv_hash.h"
21 #include "cryp_hash.h"
22 #include "ext_alg.h"
23 #include "securec.h"
24 
25 /* size of hash physical memory 1M */
26 #define HASH_PHY_MEM_SIZE               0x100000
27 
28 /* try to create memory for HASH */
29 #define HASH_PHY_MEM_CREATE_TRY_TIME    10
30 
31 /* block size */
32 #define SHA1_BLOCK_SIZE                 64
33 #define SHA224_BLOCK_SIZE               64
34 #define SHA256_BLOCK_SIZE               64
35 #define SHA384_BLOCK_SIZE               128
36 #define SHA512_BLOCK_SIZE               128
37 #define SM3_BLOCK_SIZE                  64
38 
39 /* first byte of hash padding */
40 #define HASH_PADDING_B0                 0x80
41 
42 /* Hash padding 0x80 || Len(64)  */
43 #define HASH_BLOCK64_PAD_MIN            9
44 /* Hash padding 0x80 || Len(128) */
45 #define HASH_BLOCK128_PAD_MIN           17
46 
47 /* The max tab size of symc function */
48 #define HASH_FUNC_TAB_SIZE              16
49 
50 /* SHA-1, the initial hash value, H(0) */
51 #define SHA1_H0                         0x67452301
52 #define SHA1_H1                         0xefcdab89
53 #define SHA1_H2                         0x98badcfe
54 #define SHA1_H3                         0x10325476
55 #define SHA1_H4                         0xc3d2e1f0
56 
57 /* SHA-224, the initial hash value, H(0) */
58 #define SHA224_H0                       0xc1059ed8
59 #define SHA224_H1                       0x367cd507
60 #define SHA224_H2                       0x3070dd17
61 #define SHA224_H3                       0xf70e5939
62 #define SHA224_H4                       0xffc00b31
63 #define SHA224_H5                       0x68581511
64 #define SHA224_H6                       0x64f98fa7
65 #define SHA224_H7                       0xbefa4fa4
66 
67 /* SHA-256, the initial hash value, H(0) */
68 #define SHA256_H0                       0x6a09e667
69 #define SHA256_H1                       0xbb67ae85
70 #define SHA256_H2                       0x3c6ef372
71 #define SHA256_H3                       0xa54ff53a
72 #define SHA256_H4                       0x510e527f
73 #define SHA256_H5                       0x9b05688c
74 #define SHA256_H6                       0x1f83d9ab
75 #define SHA256_H7                       0x5be0cd19
76 
77 /* SHA-384, the initial hash value, H(0) */
78 #define SHA384_H0                       0xcbbb9d5dc1059ed8ULL
79 #define SHA384_H1                       0x629a292a367cd507ULL
80 #define SHA384_H2                       0x9159015a3070dd17ULL
81 #define SHA384_H3                       0x152fecd8f70e5939ULL
82 #define SHA384_H4                       0x67332667ffc00b31ULL
83 #define SHA384_H5                       0x8eb44a8768581511ULL
84 #define SHA384_H6                       0xdb0c2e0d64f98fa7ULL
85 #define SHA384_H7                       0x47b5481dbefa4fa4ULL
86 
87 /* SHA-512, the initial hash value, H(0) */
88 #define SHA512_H0                       0x6a09e667f3bcc908ULL
89 #define SHA512_H1                       0xbb67ae8584caa73bULL
90 #define SHA512_H2                       0x3c6ef372fe94f82bULL
91 #define SHA512_H3                       0xa54ff53a5f1d36f1ULL
92 #define SHA512_H4                       0x510e527fade682d1ULL
93 #define SHA512_H5                       0x9b05688c2b3e6c1fULL
94 #define SHA512_H6                       0x1f83d9abfb41bd6bULL
95 #define SHA512_H7                       0x5be0cd19137e2179ULL
96 
97 /* SM3, the initial hash value, H(0) */
98 #define SM3_H0                          0x7380166F
99 #define SM3_H1                          0x4914B2B9
100 #define SM3_H2                          0x172442D7
101 #define SM3_H3                          0xDA8A0600
102 #define SM3_H4                          0xA96F30BC
103 #define SM3_H5                          0x163138AA
104 #define SM3_H6                          0xE38DEE4D
105 #define SM3_H7                          0xB0FB0E4E
106 
107 /* hash function list */
108 static hash_func g_hash_descriptor[HASH_FUNC_TAB_SIZE];
109 
110 #ifdef CHIP_HASH_SUPPORT
111 
112 /*
113  * \brief          hash context structure
114  */
115 typedef struct {
116     hash_mode mode;                             /* HASH mode */
117     hi_u32 block_size;                          /* HASH block size */
118     hi_u32 hash_size;                           /* HASH result size */
119     hi_u32 hard_chn;                            /* HASH hardware channel number */
120     hi_u8 tail[HASH_BLOCK_SIZE_128 * MUL_VAL_2];   /* buffer to store the tail and padding data, len is 256 bytes. */
121     hi_u32 tail_len;                            /* length of the tail message */
122     hi_u32 total;                               /* total length of the message */
123     hi_u32 hash[HASH_RESULT_MAX_SIZE_IN_WORD];  /* buffer to store the result */
124     crypto_mem mem;                             /* DMA memory of hash message */
125 } cryp_hash_context;
126 
127 /* hash dma memory */
128 static crypto_mem g_hash_mem;
129 
130 /* ****************************** API Code **************************** */
cryp_sha1_init(cryp_hash_context * hisi_ctx)131 static hi_void cryp_sha1_init(cryp_hash_context *hisi_ctx)
132 {
133     hisi_ctx->block_size = SHA1_BLOCK_SIZE;
134     hisi_ctx->hash_size = SHA1_RESULT_SIZE;
135     hisi_ctx->hash[WORD_IDX_0] = crypto_cpu_to_be32(SHA1_H0);
136     hisi_ctx->hash[WORD_IDX_1] = crypto_cpu_to_be32(SHA1_H1);
137     hisi_ctx->hash[WORD_IDX_2] = crypto_cpu_to_be32(SHA1_H2);
138     hisi_ctx->hash[WORD_IDX_3] = crypto_cpu_to_be32(SHA1_H3);
139     hisi_ctx->hash[WORD_IDX_4] = crypto_cpu_to_be32(SHA1_H4);
140 }
141 
cryp_sha2_224_init(cryp_hash_context * hisi_ctx)142 static hi_void cryp_sha2_224_init(cryp_hash_context *hisi_ctx)
143 {
144     hisi_ctx->hash_size = SHA224_RESULT_SIZE;
145     hisi_ctx->block_size = SHA224_BLOCK_SIZE;
146     hisi_ctx->hash[WORD_IDX_0] = crypto_cpu_to_be32(SHA224_H0);
147     hisi_ctx->hash[WORD_IDX_1] = crypto_cpu_to_be32(SHA224_H1);
148     hisi_ctx->hash[WORD_IDX_2] = crypto_cpu_to_be32(SHA224_H2);
149     hisi_ctx->hash[WORD_IDX_3] = crypto_cpu_to_be32(SHA224_H3);
150     hisi_ctx->hash[WORD_IDX_4] = crypto_cpu_to_be32(SHA224_H4);
151     hisi_ctx->hash[WORD_IDX_5] = crypto_cpu_to_be32(SHA224_H5);
152     hisi_ctx->hash[WORD_IDX_6] = crypto_cpu_to_be32(SHA224_H6);
153     hisi_ctx->hash[WORD_IDX_7] = crypto_cpu_to_be32(SHA224_H7);
154 }
155 
cryp_sha2_256_init(cryp_hash_context * hisi_ctx)156 static hi_void cryp_sha2_256_init(cryp_hash_context *hisi_ctx)
157 {
158     hisi_ctx->hash_size = SHA256_RESULT_SIZE;
159     hisi_ctx->block_size = SHA256_BLOCK_SIZE;
160     hisi_ctx->hash[WORD_IDX_0] = crypto_cpu_to_be32(SHA256_H0);
161     hisi_ctx->hash[WORD_IDX_1] = crypto_cpu_to_be32(SHA256_H1);
162     hisi_ctx->hash[WORD_IDX_2] = crypto_cpu_to_be32(SHA256_H2);
163     hisi_ctx->hash[WORD_IDX_3] = crypto_cpu_to_be32(SHA256_H3);
164     hisi_ctx->hash[WORD_IDX_4] = crypto_cpu_to_be32(SHA256_H4);
165     hisi_ctx->hash[WORD_IDX_5] = crypto_cpu_to_be32(SHA256_H5);
166     hisi_ctx->hash[WORD_IDX_6] = crypto_cpu_to_be32(SHA256_H6);
167     hisi_ctx->hash[WORD_IDX_7] = crypto_cpu_to_be32(SHA256_H7);
168 }
169 
170 #ifndef CHIP_TYPE_hi3516ev200
cryp_sha2_384_init(cryp_hash_context * hisi_ctx)171 static hi_void cryp_sha2_384_init(cryp_hash_context *hisi_ctx)
172 {
173     hi_s32 ret;
174     hi_u32 idx, i;
175     hi_u64 tmp_h;
176     hi_u64 arr_h[8] = { /* 8 - sha384 init array */
177         SHA384_H0, SHA384_H1, SHA384_H2, SHA384_H3,
178         SHA384_H4, SHA384_H5, SHA384_H6, SHA384_H7
179     };
180 
181     hisi_ctx->hash_size = SHA384_RESULT_SIZE;
182     hisi_ctx->block_size = SHA384_BLOCK_SIZE;
183 
184     for (i = 0, idx = 0; i < (sizeof(arr_h) / sizeof(arr_h[0])); i++) {
185         tmp_h = crypto_cpu_to_be64(arr_h[i]);
186         ret = memcpy_s(&hisi_ctx->hash[idx], DOUBLE_WORD_WIDTH, &tmp_h, sizeof(hi_u64));
187         if (ret != EOK) {
188             hi_log_print_func_err(memcpy_s, HI_ERR_CIPHER_MEMCPY_S_FAILED);
189             return;
190         }
191         idx += WORD_IDX_2;
192     }
193 }
194 
cryp_sha2_512_init(cryp_hash_context * hisi_ctx)195 static hi_void cryp_sha2_512_init(cryp_hash_context *hisi_ctx)
196 {
197     hi_s32 ret;
198     hi_u32 idx, i;
199     hi_u64 tmp_h;
200     hi_u64 arr_h[8] = { /* 8 - sha512 init array */
201         SHA512_H0, SHA512_H1, SHA512_H2, SHA512_H3,
202         SHA512_H4, SHA512_H5, SHA512_H6, SHA512_H7
203     };
204 
205     hisi_ctx->hash_size = SHA512_RESULT_SIZE;
206     hisi_ctx->block_size = SHA512_BLOCK_SIZE;
207 
208     for (i = 0, idx = 0; i < (sizeof(arr_h) / sizeof(arr_h[0])); i++) {
209         tmp_h = crypto_cpu_to_be64(arr_h[i]);
210         ret = memcpy_s(&hisi_ctx->hash[idx], DOUBLE_WORD_WIDTH, &tmp_h, sizeof(hi_u64));
211         if (ret != EOK) {
212             hi_log_print_func_err(memcpy_s, HI_ERR_CIPHER_MEMCPY_S_FAILED);
213             return;
214         }
215         idx += WORD_IDX_2;
216     }
217 }
218 #endif
219 
cryp_sm3_init(cryp_hash_context * hisi_ctx)220 static hi_void cryp_sm3_init(cryp_hash_context *hisi_ctx)
221 {
222     hisi_ctx->hash_size = SM3_RESULT_SIZE;
223     hisi_ctx->block_size = SM3_BLOCK_SIZE;
224     hisi_ctx->hash[WORD_IDX_0] = crypto_cpu_to_be32(SM3_H0);
225     hisi_ctx->hash[WORD_IDX_1] = crypto_cpu_to_be32(SM3_H1);
226     hisi_ctx->hash[WORD_IDX_2] = crypto_cpu_to_be32(SM3_H2);
227     hisi_ctx->hash[WORD_IDX_3] = crypto_cpu_to_be32(SM3_H3);
228     hisi_ctx->hash[WORD_IDX_4] = crypto_cpu_to_be32(SM3_H4);
229     hisi_ctx->hash[WORD_IDX_5] = crypto_cpu_to_be32(SM3_H5);
230     hisi_ctx->hash[WORD_IDX_6] = crypto_cpu_to_be32(SM3_H6);
231     hisi_ctx->hash[WORD_IDX_7] = crypto_cpu_to_be32(SM3_H7);
232 }
233 
cryp_hash_initial(cryp_hash_context * hisi_ctx,hash_mode mode)234 static hi_s32 cryp_hash_initial(cryp_hash_context *hisi_ctx, hash_mode mode)
235 {
236     hi_log_func_enter();
237 
238     switch (mode) {
239         case HASH_MODE_SHA1: {
240             cryp_sha1_init(hisi_ctx);
241             break;
242         }
243         case HASH_MODE_SHA224: {
244             cryp_sha2_224_init(hisi_ctx);
245             break;
246         }
247         case HASH_MODE_SHA256: {
248             cryp_sha2_256_init(hisi_ctx);
249             break;
250         }
251 #ifndef CHIP_TYPE_hi3516ev200
252         case HASH_MODE_SHA384: {
253             cryp_sha2_384_init(hisi_ctx);
254             break;
255         }
256         case HASH_MODE_SHA512: {
257             cryp_sha2_512_init(hisi_ctx);
258             break;
259         }
260 #endif
261         case HASH_MODE_SM3: {
262             cryp_sm3_init(hisi_ctx);
263             break;
264         }
265         default: {
266             hi_log_error("Invalid hash mode, mode = 0x%x.\n", mode);
267             hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARAM);
268             return HI_ERR_CIPHER_INVALID_PARAM;
269         }
270     }
271 
272     hi_log_func_exit();
273     return HI_SUCCESS;
274 }
275 
276 /*
277  * \brief          Create DMA memory of HASH message
278  */
cryp_hash_create_mem(hi_void)279 static hi_s32 cryp_hash_create_mem(hi_void)
280 {
281     hi_s32 ret;
282     hi_u32 i;
283     hi_u32 length = HASH_PHY_MEM_SIZE;
284 
285     hi_log_func_enter();
286 
287     (hi_void)memset_s(&g_hash_mem, sizeof(g_hash_mem), 0x00, sizeof(g_hash_mem));
288 
289     /* Try to alloc memory, halve the length if failed */
290     for (i = 0; i < HASH_PHY_MEM_CREATE_TRY_TIME; i++) {
291         ret = hash_mem_create(&g_hash_mem, SEC_MMZ, "hash_msg_dma", length);
292         if (ret == HI_SUCCESS) {
293             return HI_SUCCESS;
294         } else {
295             /* half the length */
296             length /= MUL_VAL_2;
297         }
298     }
299 
300     hi_log_func_exit();
301     return HI_ERR_CIPHER_FAILED_MEM;
302 }
303 
cryp_hash_destroy_mem(hi_void)304 static hi_s32 cryp_hash_destroy_mem(hi_void)
305 {
306     hi_s32 ret;
307 
308     ret = hash_mem_destroy(&g_hash_mem);
309     if (ret != HI_SUCCESS) {
310         hi_log_print_func_err(crypto_mem_destroy, ret);
311         return ret;
312     }
313 
314     hi_log_func_exit();
315     return HI_SUCCESS;
316 }
317 
cryp_hash_chunk_copy(const hi_void * chunk,hi_u32 chunk_len,hi_void * dma,hi_u32 dma_len,hash_chunk_src src)318 static hi_s32 cryp_hash_chunk_copy(const hi_void *chunk, hi_u32 chunk_len,
319     hi_void *dma, hi_u32 dma_len, hash_chunk_src src)
320 {
321     hi_s32 ret;
322 
323     hi_log_func_enter();
324 
325     /* Don't process the empty message */
326     if ((chunk_len == 0x00) || (dma_len < chunk_len)) {
327         hi_log_func_exit();
328         return HI_SUCCESS;
329     }
330 
331     hi_log_chk_param_return(chunk == HI_NULL);
332     hi_log_chk_param_return(dma   == HI_NULL);
333 
334     if (src == HASH_CHUNCK_SRC_LOCAL) {
335         if (memcpy_s(dma, dma_len, chunk, chunk_len) != EOK) {
336             hi_log_print_func_err(memcpy_s, HI_ERR_CIPHER_MEMCPY_S_FAILED);
337             return HI_ERR_CIPHER_MEMCPY_S_FAILED;
338         }
339     } else {
340         ret = crypto_copy_from_user(dma, dma_len, chunk, chunk_len);
341         if (ret != HI_SUCCESS) {
342             hi_log_print_func_err(crypto_copy_from_user, ret);
343             return ret;
344         }
345     }
346 
347     hi_log_func_exit();
348     return HI_SUCCESS;
349 }
350 
351 /* hash hardware computation */
cryp_hash_process(cryp_hash_context * hisi_ctx,const hi_u8 * msg,hi_u32 length,hash_chunk_src src)352 static hi_s32 cryp_hash_process(cryp_hash_context *hisi_ctx, const hi_u8 *msg, hi_u32 length, hash_chunk_src src)
353 {
354     hi_s32 ret;
355     hi_void *buf = HI_NULL;
356     hi_u32 left, size, max;
357 
358     hi_log_func_enter();
359 
360     /* Don't process the empty message */
361     if (length == 0x00) {
362         hi_log_func_exit();
363         return HI_SUCCESS;
364     }
365 
366     hi_log_debug("length 0x%x, dma_size 0x%x\n", length, hisi_ctx->mem.dma_size);
367 
368     /* get dma buffer */
369     buf = crypto_mem_virt(&hisi_ctx->mem);
370 
371     /* align at block size */
372     max = hisi_ctx->mem.dma_size - hisi_ctx->mem.dma_size % hisi_ctx->block_size;
373 
374     /* re-compute left length */
375     for (left = length; left > 0; left -= size, msg += size) {
376         if (left <= max) {
377             /* left size less than dma buffer,
378              * can process all left message
379              */
380             size = left;
381         } else {
382             /* left size large than dma buffer,
383              * just process message with dma size
384              */
385             size = max;
386         }
387 
388         hi_log_debug("msg 0x%pK, size 0x%x, left 0x%x, max 0x%x\n", msg, size, left, max);
389 
390         /* copy message to dma buffer */
391         ret = cryp_hash_chunk_copy(msg, size, buf, size, src);
392         if (ret != HI_SUCCESS) {
393             hi_log_print_func_err(cryp_hash_chunk_copy, ret);
394             return ret;
395         }
396 
397         /* configure mode */
398         ret = drv_hash_cfg(hisi_ctx->hard_chn, hisi_ctx->mode, hisi_ctx->hash);
399         if (ret != HI_SUCCESS) {
400             hi_log_print_func_err(drv_hash_cfg, ret);
401             return ret;
402         }
403 
404         /* start */
405         ret = drv_hash_start(hisi_ctx->hard_chn, &hisi_ctx->mem, size);
406         if (ret != HI_SUCCESS) {
407             hi_log_print_func_err(drv_hash_start, ret);
408             return ret;
409         }
410 
411         /* wait done */
412         ret = drv_hash_wait_done(hisi_ctx->hard_chn, hisi_ctx->hash);
413         if (ret != HI_SUCCESS) {
414             hi_log_print_func_err(drv_hash_wait_done, ret);
415             return ret;
416         }
417     }
418 
419     hi_log_func_exit();
420     return HI_SUCCESS;
421 }
422 
423 /* hash message padding to align at block size */
cryp_hash_pading(hi_u32 block_size,hi_u8 * msg,hi_u32 tail_size,hi_u32 total)424 static hi_u32 cryp_hash_pading(hi_u32 block_size, hi_u8 *msg, hi_u32 tail_size, hi_u32 total)
425 {
426     hi_u32 pad_len, min;
427 
428     hi_log_func_enter();
429 
430     /* get min padding size */
431     if (block_size == HASH_BLOCK_SIZE_64) {
432         min = HASH_BLOCK64_PAD_MIN;
433     } else {
434         min = HASH_BLOCK128_PAD_MIN;
435     }
436 
437     pad_len = block_size - (total % block_size);
438 
439     /* if pad len less than min value, add a block */
440     if (pad_len < min) {
441         pad_len += block_size;
442     }
443 
444     /* Format(binary): data || 0x80 || 00 00 ... || Len(64) */
445     (hi_void)memset_s(&msg[tail_size], HASH_BLOCK_SIZE_128 * MUL_VAL_2 - tail_size, 0, pad_len);
446     msg[tail_size] = HASH_PADDING_B0;
447     tail_size += pad_len - WORD_WIDTH * MUL_VAL_2; /* Two word length left. */
448 
449     /* write 8 bytes fix data length * 8 */
450     msg[tail_size++] = 0x00;
451     msg[tail_size++] = 0x00;
452     msg[tail_size++] = 0x00;
453     msg[tail_size++] = (hi_u8)((total >> SHIFT_29BITS) & MAX_LOW_3BITS);
454     msg[tail_size++] = (hi_u8)((total >> SHIFT_21BITS) & MAX_LOW_8BITS);
455     msg[tail_size++] = (hi_u8)((total >> SHIFT_13BITS) & MAX_LOW_8BITS);
456     msg[tail_size++] = (hi_u8)((total >> SHIFT_5BITS)  & MAX_LOW_8BITS);
457     msg[tail_size++] = (hi_u8)((total << SHIFT_3BITS)  & MAX_LOW_8BITS);
458 
459     hi_log_func_exit();
460 
461     return tail_size;
462 }
463 
cryp_hash_create(hash_mode mode)464 static hi_void *cryp_hash_create(hash_mode mode)
465 {
466     hi_s32 ret;
467     cryp_hash_context *hisi_ctx = HI_NULL;
468 
469     hi_log_func_enter();
470 
471     hisi_ctx = crypto_calloc(MUL_VAL_1, sizeof(cryp_hash_context));
472     if (hisi_ctx == HI_NULL) {
473         hi_log_error("malloc hash context buffer failed!");
474         hi_log_print_err_code(HI_ERR_CIPHER_FAILED_MEM);
475         return HI_NULL;
476     }
477 
478     hisi_ctx->mode = mode;
479     hisi_ctx->hard_chn = HASH_HARD_CHANNEL;
480 
481     ret = cryp_hash_initial(hisi_ctx, mode);
482     if (ret != HI_SUCCESS) {
483         hi_log_print_func_err(cryp_hash_initial, ret);
484         goto error1;
485     }
486 
487     if (memcpy_s(&hisi_ctx->mem, sizeof(crypto_mem), &g_hash_mem, sizeof(crypto_mem)) != EOK) {
488         hi_log_print_func_err(memcpy_s, HI_ERR_CIPHER_MEMCPY_S_FAILED);
489         ret = HI_ERR_CIPHER_MEMCPY_S_FAILED;
490         goto error1;
491     }
492 
493     hi_log_func_exit();
494 
495     return hisi_ctx;
496 
497 error1:
498     crypto_free(hisi_ctx);
499     hisi_ctx = HI_NULL;
500 
501     return HI_NULL;
502 }
503 
cryp_hash_destroy(hi_void * ctx)504 static hi_s32 cryp_hash_destroy(hi_void *ctx)
505 {
506     cryp_hash_context *hisi_ctx = ctx;
507 
508     hi_log_func_enter();
509     if (hisi_ctx == HI_NULL) {
510         hi_log_func_exit();
511         return HI_SUCCESS;
512     }
513 
514     drv_hash_reset(hisi_ctx->hard_chn);
515     crypto_free(ctx);
516     ctx = HI_NULL;
517 
518     hi_log_func_exit();
519     return HI_SUCCESS;
520 }
521 
cryp_hash_update(hi_void * ctx,const hi_u8 * chunk,hi_u32 chunk_len,hash_chunk_src src)522 static hi_s32 cryp_hash_update(hi_void *ctx, const hi_u8 *chunk, hi_u32 chunk_len, hash_chunk_src src)
523 {
524     hi_s32 ret;
525     cryp_hash_context *hisi_ctx = ctx;
526     hi_u32 inverse_len;
527 
528     hi_log_func_enter();
529     hi_log_chk_param_return(hisi_ctx == HI_NULL);
530 
531     hi_log_debug("last: total 0x%x, block size %u, tail_len %u, chunk_len 0x%x, src %d\n", hisi_ctx->total,
532                  hisi_ctx->block_size, hisi_ctx->tail_len, chunk_len, src);
533 
534     /* total len */
535     hisi_ctx->total += chunk_len;
536 
537     /* left tail len to make up a block */
538     inverse_len = hisi_ctx->block_size - hisi_ctx->tail_len;
539 
540     if (chunk_len  < inverse_len) {
541         /* can't make up a block */
542         inverse_len = chunk_len;
543     }
544 
545     /* try to make up the tail data to be a block */
546     ret = cryp_hash_chunk_copy(chunk, inverse_len, hisi_ctx->tail + hisi_ctx->tail_len, inverse_len, src);
547     if (ret != HI_SUCCESS) {
548         hi_log_print_func_err(cryp_hash_chunk_copy, ret);
549         return ret;
550     }
551     hisi_ctx->tail_len += inverse_len;
552     chunk += inverse_len;
553     chunk_len -= inverse_len;  /* the chunk_len may be zero */
554 
555     hi_log_debug("new: total 0x%x, tail_len %u, chunk_len 0x%x\n", hisi_ctx->total, hisi_ctx->tail_len, chunk_len);
556 
557     /* process tail block */
558     if (hisi_ctx->tail_len == hisi_ctx->block_size) {
559         ret = cryp_hash_process(hisi_ctx, hisi_ctx->tail, hisi_ctx->tail_len, HASH_CHUNCK_SRC_LOCAL);
560         if (ret != HI_SUCCESS) {
561             hi_log_print_func_err(cryp_hash_process, ret);
562             return ret;
563         }
564 
565         /* new tail len */
566         hisi_ctx->tail_len = chunk_len % hisi_ctx->block_size;
567 
568         /* new chunk len align at block size */
569         chunk_len -= hisi_ctx->tail_len;
570 
571         /* save new tail */
572         ret = cryp_hash_chunk_copy(chunk + chunk_len, hisi_ctx->tail_len, hisi_ctx->tail, hisi_ctx->tail_len, src);
573         if (ret != HI_SUCCESS) {
574             hi_log_print_func_err(cryp_hash_chunk_copy, ret);
575             return ret;
576         }
577     }
578 
579     hi_log_debug("new: total 0x%x, tail_len %u, chunk_len 0x%x\n", hisi_ctx->total, hisi_ctx->tail_len, chunk_len);
580 
581     /* process left block, just return HI_SUCCESS if the chunk_len is zero */
582     ret = cryp_hash_process(hisi_ctx, chunk, chunk_len, src);
583     if (ret != HI_SUCCESS) {
584         hi_log_print_func_err(cryp_hash_process, ret);
585         return ret;
586     }
587 
588     hi_log_func_exit();
589     return HI_SUCCESS;
590 }
591 
cryp_hash_finish(hi_void * ctx,hi_void * hash,hi_u32 hash_buf_len,hi_u32 * hashlen)592 static hi_s32 cryp_hash_finish(hi_void *ctx,  hi_void *hash, hi_u32 hash_buf_len, hi_u32 *hashlen)
593 {
594     hi_s32 ret;
595     cryp_hash_context *hisi_ctx = ctx;
596     hi_u32 left;
597 
598     hi_log_func_enter();
599     hi_log_chk_param_return(hisi_ctx == HI_NULL);
600 
601     /* padding message */
602     left = cryp_hash_pading(hisi_ctx->block_size, hisi_ctx->tail, hisi_ctx->tail_len, hisi_ctx->total);
603     ret = cryp_hash_process(hisi_ctx, hisi_ctx->tail, left, HASH_CHUNCK_SRC_LOCAL);
604     if (ret != HI_SUCCESS) {
605         hi_log_print_func_err(cryp_hash_process, ret);
606         return ret;
607     }
608 
609     if (memcpy_s(hash, hash_buf_len, hisi_ctx->hash, hisi_ctx->hash_size) != EOK) {
610         hi_log_print_func_err(memcpy_s, HI_ERR_CIPHER_MEMCPY_S_FAILED);
611         return HI_ERR_CIPHER_MEMCPY_S_FAILED;
612     }
613     *hashlen = hisi_ctx->hash_size;
614 
615     hi_log_func_exit();
616     return HI_SUCCESS;
617 }
618 #endif
619 
func_register_hash(const hash_func * func)620 static hi_s32 func_register_hash(const hash_func *func)
621 {
622     hi_u32 i;
623 
624     hi_log_func_enter();
625 
626     /* check availability */
627     if ((func->create  == HI_NULL) || (func->destroy == HI_NULL) || (func->update == HI_NULL) ||
628         (func->finish == HI_NULL)) {
629         hi_log_error("hash function is null.\n");
630         hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARAM);
631         return HI_ERR_CIPHER_INVALID_PARAM;
632     }
633 
634     hi_log_debug("register hash mode %u\n", func->mode);
635 
636     /* is it already registered? */
637     for (i = 0; i < HASH_FUNC_TAB_SIZE; i++) {
638         if (g_hash_descriptor[i].valid && g_hash_descriptor[i].mode == func->mode) {
639             hi_log_func_exit();
640             return HI_SUCCESS;
641         }
642     }
643 
644     /* find a blank spot */
645     for (i = 0; i < HASH_FUNC_TAB_SIZE; i++) {
646         if (!g_hash_descriptor[i].valid) {
647             g_hash_descriptor[i] = *func;
648             g_hash_descriptor[i].valid = HI_TRUE;
649             hi_log_func_exit();
650             return HI_SUCCESS;
651         }
652     }
653 
654     return HI_ERR_CIPHER_INVALID_PARAM;
655 }
656 
657 /* hash function register */
cryp_register_hash_default(hi_u32 capacity,hash_mode mode,hi_u32 blocksize,hi_u32 hashlen)658 static hi_void cryp_register_hash_default(hi_u32 capacity, hash_mode mode, hi_u32 blocksize, hi_u32 hashlen)
659 {
660     hash_func func;
661 
662     (hi_void)memset_s(&func, sizeof(func), 0, sizeof(func));
663 
664     /* register the hash function if supported */
665     if (capacity) {
666 #ifdef CHIP_HASH_SUPPORT
667         func.mode = mode;
668         func.block_size = blocksize;
669         func.size = hashlen;
670         func.create = cryp_hash_create;
671         func.destroy = cryp_hash_destroy;
672         func.update = cryp_hash_update;
673         func.finish = cryp_hash_finish;
674         func_register_hash(&func);
675 #endif
676     } else if (mode == HASH_MODE_SM3) {
677 #if defined(SOFT_SM3_SUPPORT)
678         func.mode = mode;
679         func.block_size = blocksize;
680         func.size = hashlen;
681         func.create = ext_sm3_create;
682         func.destroy = ext_sm3_destroy;
683         func.update = ext_sm3_update;
684         func.finish = ext_sm3_finish;
685         func_register_hash(&func);
686 #endif
687     } else {
688 #if defined(SOFT_SHA1_SUPPORT) || defined(SOFT_SHA256_SUPPORT) || defined(SOFT_SHA512_SUPPORT)
689         func.mode = mode;
690         func.block_size = blocksize;
691         func.size = hashlen;
692         func.create = mbedtls_hash_create;
693         func.destroy = mbedtls_hash_destroy;
694         func.update = mbedtls_hash_update;
695         func.finish = mbedtls_hash_finish;
696         func_register_hash(&func);
697 #endif
698     }
699     return;
700 }
701 
702 /* hash function register */
cryp_register_all_hash(hi_void)703 static hi_void cryp_register_all_hash(hi_void)
704 {
705     hash_capacity capacity;
706 
707     (hi_void)memset_s(&capacity, sizeof(capacity), 0, sizeof(capacity));
708 
709 #ifdef CHIP_HASH_SUPPORT
710     /* get hash capacity */
711     drv_hash_get_capacity(&capacity);
712 #endif
713 
714     cryp_register_hash_default(capacity.sha1, HASH_MODE_SHA1, SHA1_BLOCK_SIZE, SHA1_RESULT_SIZE);
715     cryp_register_hash_default(capacity.sha224, HASH_MODE_SHA224, SHA224_BLOCK_SIZE, SHA224_RESULT_SIZE);
716     cryp_register_hash_default(capacity.sha256, HASH_MODE_SHA256, SHA256_BLOCK_SIZE, SHA256_RESULT_SIZE);
717     cryp_register_hash_default(capacity.sha384, HASH_MODE_SHA384, SHA384_BLOCK_SIZE, SHA384_RESULT_SIZE);
718     cryp_register_hash_default(capacity.sha512, HASH_MODE_SHA512, SHA512_BLOCK_SIZE, SHA512_RESULT_SIZE);
719     cryp_register_hash_default(capacity.sm3, HASH_MODE_SM3, SM3_BLOCK_SIZE, SM3_RESULT_SIZE);
720 
721     return;
722 }
723 
cryp_get_hash(hi_u32 mode)724 hash_func *cryp_get_hash(hi_u32 mode)
725 {
726     hi_u32 i;
727     hash_func *template = HI_NULL;
728 
729     hi_log_func_enter();
730 
731     /* find the valid function */
732     for (i = 0; i < HASH_FUNC_TAB_SIZE; i++) {
733         if (g_hash_descriptor[i].valid && (g_hash_descriptor[i].mode == mode)) {
734             template = &g_hash_descriptor[i];
735             break;
736         }
737     }
738 
739     hi_log_func_exit();
740     return template;
741 }
742 
cryp_hash_init(hi_void)743 hi_s32 cryp_hash_init(hi_void)
744 {
745     hi_log_func_enter();
746 
747     (hi_void)memset_s(g_hash_descriptor, sizeof(g_hash_descriptor), 0, sizeof(g_hash_descriptor));
748 
749 #ifdef CHIP_HASH_SUPPORT
750     {
751         hi_s32 ret;
752 
753         ret = drv_hash_init();
754         if (ret != HI_SUCCESS) {
755             hi_log_print_func_err(drv_hash_init, ret);
756             return ret;
757         }
758 
759         ret = cryp_hash_create_mem();
760         if (ret != HI_SUCCESS) {
761             hi_log_print_func_err(cryp_hash_create_mem, ret);
762             drv_hash_deinit();
763             return ret;
764         }
765     }
766 #endif
767 
768     /* hash function register */
769     cryp_register_all_hash();
770 
771     hi_log_func_exit();
772     return HI_SUCCESS;
773 }
774 
cryp_hash_deinit(hi_void)775 hi_void cryp_hash_deinit(hi_void)
776 {
777     hi_s32 ret;
778     hi_log_func_enter();
779 
780 #ifdef CHIP_HASH_SUPPORT
781     ret = drv_hash_deinit();
782     if (ret != HI_SUCCESS) {
783         hi_log_print_func_err(drv_hash_deinit, ret);
784     }
785 
786     ret = cryp_hash_destroy_mem();
787     if (ret != HI_SUCCESS) {
788         hi_log_print_func_err(cryp_hash_destroy_mem, ret);
789         return;
790     }
791 #endif
792 
793     hi_log_func_exit();
794 }
795