• 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 "cryp_hash.h"
21 #include "mbedtls/md.h"
22 #include "securec.h"
23 
24 #define HASH_MAX_BUFFER_SIZE    0x100000 /* 1M */
25 
26 #if defined(SOFT_SHA1_SUPPORT) || defined(SOFT_SHA256_SUPPORT) || defined(SOFT_SHA512_SUPPORT)
27 
mbedtls_hash_create(hash_mode mode)28 hi_void *mbedtls_hash_create(hash_mode mode)
29 {
30     mbedtls_md_type_t md_type;
31     const mbedtls_md_info_t *info;
32     mbedtls_md_context_t *ctx = HI_NULL;
33 
34     hi_log_func_enter();
35 
36     /* convert to mbedtls type */
37     md_type = MBEDTLS_MD_SHA1 + (mode - HASH_MODE_SHA1);
38 
39     info = mbedtls_md_info_from_type(md_type);
40     if (info == HI_NULL) {
41         hi_log_error("error, invalid hash mode %d\n", mode);
42         hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARAM);
43         return HI_NULL;
44     }
45 
46     ctx = crypto_malloc(sizeof(*ctx));
47     if (ctx == HI_NULL) {
48         hi_log_error("malloc hash context buffer failed!");
49         hi_log_print_err_code(HI_ERR_CIPHER_FAILED_MEM);
50         return HI_NULL;
51     }
52     (hi_void)memset_s(ctx, sizeof(mbedtls_md_context_t), 0, sizeof(mbedtls_md_context_t));
53 
54     mbedtls_md_init(ctx);
55     mbedtls_md_setup(ctx, info, HI_FALSE);
56     mbedtls_md_starts(ctx);
57 
58     hi_log_func_exit();
59 
60     return ctx;
61 }
62 
ext_hash_update_from_user(mbedtls_md_context_t * md,hi_u8 * chunk,hi_u32 chunk_len)63 static hi_s32 ext_hash_update_from_user(mbedtls_md_context_t *md, hi_u8 *chunk, hi_u32 chunk_len)
64 {
65     hi_s32 ret;
66     hi_u8 *ptr = HI_NULL;
67     hi_u32 len;
68     hi_u32 offset = 0;
69 
70     ptr = crypto_calloc(HASH_MAX_BUFFER_SIZE);
71     if (ptr == HI_NULL) {
72         hi_log_print_func_err(crypto_malloc, HI_ERR_CIPHER_FAILED_MEM);
73         return HI_ERR_CIPHER_FAILED_MEM;
74     }
75 
76     while (offset < chunk_len) {
77         len = chunk_len - offset;
78         if (len > HASH_MAX_BUFFER_SIZE) {
79             len = HASH_MAX_BUFFER_SIZE;
80         }
81         ret = crypto_copy_from_user(ptr, HASH_MAX_BUFFER_SIZE, chunk + offset, len);
82         if (ret != HI_SUCCESS) {
83             hi_log_print_func_err(crypto_copy_from_user, ret);
84             crypto_free(ptr);
85             ptr = HI_NULL;
86             return HI_ERR_CIPHER_FAILED_MEM;
87         }
88         ret = mbedtls_md_update(md, ptr, len);
89         if (ret != HI_SUCCESS) {
90             hi_log_print_func_err(mbedtls_md_update, ret);
91             crypto_free(ptr);
92             ptr = HI_NULL;
93             return ret;
94         }
95         crypto_msleep(1);
96         offset += len;
97     }
98 
99     if (ptr != HI_NULL) {
100         crypto_free(ptr);
101         ptr = HI_NULL;
102     }
103 
104     return HI_SUCCESS;
105 }
106 
mbedtls_hash_update(hi_void * ctx,const hi_u8 * chunk,hi_u32 chunk_len,hash_chunk_src src)107 hi_s32 mbedtls_hash_update(hi_void *ctx, const hi_u8 *chunk, hi_u32 chunk_len, hash_chunk_src src)
108 {
109     hi_u8 *ptr = HI_NULL;
110     hi_s32 ret;
111     mbedtls_md_context_t *md = ctx;
112 
113     hi_log_func_enter();
114 
115     hi_log_chk_param_return(ctx == HI_NULL);
116 
117     if (chunk_len == 0x00) {
118         return HI_SUCCESS;
119     }
120 
121     if (src == HASH_CHUNCK_SRC_USER) {
122         ret = ext_hash_update_from_user(md, chunk, chunk_len);
123         if (ret != HI_SUCCESS) {
124             hi_log_print_func_err(mbedtls_md_update, ret);
125             return ret;
126         }
127     } else {
128         ret = mbedtls_md_update(md, chunk, chunk_len);
129         if (ret != HI_SUCCESS) {
130             hi_log_print_func_err(mbedtls_md_update, ret);
131             return ret;
132         }
133     }
134 
135     hi_log_func_exit();
136     return HI_SUCCESS;
137 }
138 
mbedtls_hash_finish(hi_void * ctx,hi_void * hash,hi_u32 hash_buf_len,hi_u32 * hashlen)139 hi_s32 mbedtls_hash_finish(hi_void *ctx,  hi_void *hash, hi_u32 hash_buf_len, hi_u32 *hashlen)
140 {
141     mbedtls_md_context_t *md = ctx;
142 
143     hi_log_func_enter();
144 
145     hi_log_chk_param_return(ctx == HI_NULL);
146     hi_log_chk_param_return(hash_buf_len == 0);
147 
148     mbedtls_md_finish(md, hash);
149 
150     *hashlen = mbedtls_md_get_size(md->md_info);
151 
152     hi_log_func_exit();
153     return HI_SUCCESS;
154 }
155 
mbedtls_hash_destory(hi_void * ctx)156 hi_s32 mbedtls_hash_destory(hi_void *ctx)
157 {
158     mbedtls_md_context_t *md = ctx;
159 
160     hi_log_func_enter();
161 
162     hi_log_chk_param_return(ctx == HI_NULL);
163 
164     mbedtls_md_free(md);
165     crypto_free(ctx);
166     ctx = HI_NULL;
167 
168     hi_log_func_exit();
169     return HI_SUCCESS;
170 }
171 
172 #endif /* End of SOFT_AES_CCM_GCM_SUPPORT */
173