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_symc.h"
21 #include "mbedtls/cipher.h"
22 #include "securec.h"
23
24 #if defined(SOFT_AES_SUPPORT) || defined(SOFT_TDES_SUPPORT)
25
26 /*
27 * brief aes ccm context structure
28 */
29 typedef struct {
30 hi_u32 key[SYMC_KEY_SIZE / WORD_WIDTH]; /* symc even round keys, default */
31 hi_u32 klen; /* symc key length */
32 mbedtls_cipher_id_t cipher_id;
33 mbedtls_cipher_mode_t mode;
34 mbedtls_cipher_context_t cipher;
35 } ext_symc_context;
36
ext_mbedtls_symc_create(hi_u32 hard_chn)37 hi_void *ext_mbedtls_symc_create(hi_u32 hard_chn)
38 {
39 ext_symc_context *ctx = HI_NULL;
40
41 hi_log_func_enter();
42
43 ctx = crypto_malloc(sizeof(ext_symc_context));
44 if (ctx == HI_NULL) {
45 hi_log_print_err_code(HI_ERR_CIPHER_FAILED_MEM);
46 hi_log_error("malloc failed \n");
47 return HI_NULL;
48 }
49 (hi_void)memset_s(ctx, sizeof(ext_symc_context), 0, sizeof(ext_symc_context));
50
51 mbedtls_cipher_init(&ctx->cipher);
52
53 hi_log_func_exit();
54
55 return ctx;
56 }
57
ext_mbedtls_symc_destory(hi_void * ctx)58 hi_s32 ext_mbedtls_symc_destory(hi_void *ctx)
59 {
60 ext_symc_context *symc = ctx;
61
62 hi_log_func_enter();
63
64 if (ctx != HI_NULL) {
65 mbedtls_cipher_free(&symc->cipher);
66 crypto_free(ctx);
67 ctx = HI_NULL;
68 }
69
70 hi_log_func_exit();
71 return HI_SUCCESS;
72 }
73
ext_mbedtls_symc_setmode(hi_void * ctx,symc_alg alg,symc_mode mode,symc_width width)74 hi_s32 ext_mbedtls_symc_setmode(hi_void *ctx, symc_alg alg, symc_mode mode, symc_width width)
75 {
76 ext_symc_context *symc = ctx;
77
78 hi_log_func_enter();
79
80 hi_log_chk_param_return(symc == HI_NULL);
81 hi_log_chk_param_return(width != SYMC_DAT_WIDTH_128);
82
83 switch (alg) {
84 case SYMC_ALG_AES:
85 symc->cipher_id = MBEDTLS_CIPHER_ID_AES;
86 break;
87 case SYMC_ALG_TDES:
88 symc->cipher_id = MBEDTLS_CIPHER_ID_3DES;
89 break;
90 case SYMC_ALG_DES:
91 symc->cipher_id = MBEDTLS_CIPHER_ID_DES;
92 break;
93 default:
94 hi_log_error("unsupported alg %d\n", alg);
95 hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARAM);
96 return HI_ERR_CIPHER_INVALID_PARAM;
97 }
98
99 switch (mode) {
100 case SYMC_MODE_ECB:
101 symc->mode = MBEDTLS_MODE_ECB;
102 break;
103 case SYMC_MODE_CBC:
104 symc->mode = MBEDTLS_MODE_CBC;
105 break;
106 case SYMC_MODE_CFB:
107 symc->mode = MBEDTLS_MODE_CFB;
108 break;
109 case SYMC_MODE_OFB:
110 symc->mode = MBEDTLS_MODE_OFB;
111 break;
112 case SYMC_MODE_CTR:
113 symc->mode = MBEDTLS_MODE_CTR;
114 break;
115 default:
116 hi_log_error("unsupported mode %d\n", mode);
117 hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARAM);
118 return HI_ERR_CIPHER_INVALID_PARAM;
119 }
120
121 hi_log_debug("cipher_id %d, mode %d\n", symc->cipher_id, symc->mode);
122
123 hi_log_func_exit();
124 return HI_SUCCESS;
125 }
126
ext_mbedtls_symc_setiv(hi_void * ctx,const hi_u8 * iv,hi_u32 ivlen,hi_u32 usage)127 hi_s32 ext_mbedtls_symc_setiv(hi_void *ctx, const hi_u8 *iv, hi_u32 ivlen, hi_u32 usage)
128 {
129 hi_s32 ret;
130 ext_symc_context *symc = ctx;
131
132 hi_log_func_enter();
133
134 hi_log_chk_param_return(symc == HI_NULL);
135 hi_log_chk_param_return(iv == HI_NULL);
136 hi_log_chk_param_return(ivlen > AES_IV_SIZE);
137
138 ret = mbedtls_cipher_set_iv(&symc->cipher, iv, ivlen);
139
140 hi_log_func_exit();
141
142 return ret;
143 }
144
ext_mbedtls_symc_getiv(hi_void * ctx,hi_u8 * iv,hi_u32 * ivlen)145 hi_s32 ext_mbedtls_symc_getiv(hi_void *ctx, hi_u8 *iv, hi_u32 *ivlen)
146 {
147 ext_symc_context *symc = ctx;
148
149 hi_log_func_enter();
150
151 hi_log_chk_param_return(symc == HI_NULL);
152 hi_log_chk_param_return(iv == HI_NULL);
153 hi_log_chk_param_return(ivlen == HI_NULL);
154
155 if (memcpy_s(iv, AES_IV_SIZE, symc->cipher.iv, symc->cipher.iv_size) != EOK) {
156 hi_log_print_func_err(memcpy_s, HI_ERR_CIPHER_MEMCPY_S_FAILED);
157 return HI_ERR_CIPHER_MEMCPY_S_FAILED;
158 }
159 *ivlen = symc->cipher.iv_size;
160
161 hi_log_func_exit();
162
163 return HI_SUCCESS;
164 }
165
ext_mbedtls_symc_setkey(hi_void * ctx,const hi_u8 * fkey,const hi_u8 * skey,hi_u32 * hisi_klen)166 hi_s32 ext_mbedtls_symc_setkey(hi_void *ctx, const hi_u8 *fkey, const hi_u8 *skey, hi_u32 *hisi_klen)
167 {
168 hi_s32 ret;
169 hi_u32 klen = 0;
170 ext_symc_context *symc = ctx;
171 const mbedtls_cipher_info_t *info = HI_NULL;
172
173 hi_log_func_enter();
174
175 hi_log_chk_param_return(symc == HI_NULL);
176 hi_log_chk_param_return(fkey == HI_NULL);
177 hi_log_chk_param_return(hisi_klen == HI_NULL);
178
179 if (symc->cipher_id == MBEDTLS_CIPHER_ID_AES) {
180 if (*hisi_klen == HI_CIPHER_KEY_AES_128BIT) {
181 klen = AES_KEY_128BIT;
182 } else if (*hisi_klen == HI_CIPHER_KEY_AES_192BIT) {
183 klen = AES_KEY_192BIT;
184 } else if (*hisi_klen == HI_CIPHER_KEY_AES_256BIT) {
185 klen = AES_KEY_256BIT;
186 } else {
187 hi_log_error("Invalid aes key len: %u\n", *hisi_klen);
188 hi_log_print_err_code(HI_ERR_CIPHER_INVALID_PARAM);
189 return HI_ERR_CIPHER_INVALID_PARAM;
190 }
191 } else if (symc->cipher_id == MBEDTLS_CIPHER_ID_3DES) {
192 klen = TDES_KEY_192BIT;
193 } else if (symc->cipher_id == MBEDTLS_CIPHER_ID_DES) {
194 klen = DES_KEY_SIZE;
195 } else {
196 hi_log_error("Invalid cipher id: %d\n", symc->cipher_id);
197 return HI_ERR_CIPHER_INVALID_PARAM;
198 }
199 if (memcpy_s(symc->key, SYMC_KEY_SIZE, fkey, klen) != EOK) {
200 hi_log_print_func_err(memcpy_s, HI_ERR_CIPHER_MEMCPY_S_FAILED);
201 return HI_ERR_CIPHER_MEMCPY_S_FAILED;
202 }
203 if (symc->cipher_id == MBEDTLS_CIPHER_ID_3DES && *hisi_klen == HI_CIPHER_KEY_DES_2KEY) {
204 /* descript: k3 = k1 */
205 symc->key[WORD_IDX_4] = symc->key[WORD_IDX_0];
206 symc->key[WORD_IDX_5] = symc->key[WORD_IDX_1];
207 }
208
209 hi_log_info("key len %u, type %u\n", klen, *hisi_klen);
210
211 symc->klen = klen;
212
213 hi_log_debug("cipher_id %d, klen %u, mode %d\n", symc->cipher_id, klen, symc->mode);
214 info = mbedtls_cipher_info_from_values(symc->cipher_id, klen * BYTE_BITS, symc->mode);
215 hi_log_chk_param_return(info == HI_NULL);
216
217 ret = mbedtls_cipher_setup(&symc->cipher, info);
218
219 *hisi_klen = klen;
220
221 hi_log_func_exit();
222
223 return ret;
224 }
225
ext_symc_update(ext_symc_context * symc,crypto_mem * mem_in,crypto_mem * mem_out,hi_u32 len,hi_u32 * olen)226 static hi_s32 ext_symc_update(ext_symc_context *symc, crypto_mem *mem_in, crypto_mem *mem_out, hi_u32 len, hi_u32 *olen)
227 {
228 hi_s32 ret;
229 if (symc->mode == MBEDTLS_MODE_ECB) {
230 hi_u32 offset = 0;
231 while (offset < len) {
232 ret = mbedtls_cipher_update(symc->cipher, crypto_mem_virt(mem_in) + offset,
233 mbedtls_cipher_get_block_size(symc->cipher), crypto_mem_virt(mem_out) + offset, olen);
234 if (ret != HI_SUCCESS) {
235 hi_log_print_func_err(mbedtls_cipher_update, ret);
236 return ret;
237 }
238 offset += mbedtls_cipher_get_block_size(symc->cipher);
239 }
240 } else {
241 ret = mbedtls_cipher_update(symc->cipher, crypto_mem_virt(mem_in), len, crypto_mem_virt(mem_out), olen);
242 if (ret != HI_SUCCESS) {
243 hi_log_print_func_err(mbedtls_cipher_update, ret);
244 return ret;
245 }
246 }
247
248 return HI_SUCCESS;
249 }
250
ext_mbedtls_symc_crypto(hi_void * ctx,hi_u32 operation,symc_multi_pack * pack,hi_u32 last)251 hi_s32 ext_mbedtls_symc_crypto(hi_void *ctx, hi_u32 operation, symc_multi_pack *pack, hi_u32 last)
252 {
253 ext_symc_context *symc = ctx;
254 crypto_mem mem_in, mem_out;
255 size_t olen = 0;
256 hi_s32 ret;
257
258 hi_log_func_enter();
259
260 hi_log_chk_param_return(symc == HI_NULL);
261 hi_log_chk_param_return(pack == HI_NULL);
262 hi_log_chk_param_return(pack->in == HI_NULL);
263 hi_log_chk_param_return(pack->out == HI_NULL);
264 hi_log_chk_param_return(pack->len == HI_NULL);
265 hi_log_chk_param_return(pack->num != 0x01);
266
267 ret = mbedtls_cipher_setkey(&symc->cipher, (hi_u8 *)symc->key, symc->klen * BYTE_BITS,
268 operation ? MBEDTLS_DECRYPT : MBEDTLS_ENCRYPT);
269 if (ret != HI_SUCCESS) {
270 hi_log_print_func_err(mbedtls_cipher_setkey, ret);
271 return ret;
272 }
273
274 ret = crypto_mem_open(&mem_in, pack->in[0], pack->len[0]);
275 if (ret != HI_SUCCESS) {
276 hi_log_print_func_err(crypto_mem_open, ret);
277 return ret;
278 }
279
280 ret = crypto_mem_open(&mem_out, pack->out[0], pack->len[0]);
281 if (ret != HI_SUCCESS) {
282 hi_log_print_func_err(crypto_mem_open, ret);
283 crypto_mem_close(&mem_in);
284 return ret;
285 }
286
287 hi_log_debug("symc 0x%pK, klen len: %u\n", symc, symc->klen);
288
289 ret = ext_symc_update(symc, mem_in, mem_out, pack->len[0], &olen);
290 if (ret != HI_SUCCESS) {
291 hi_log_print_func_err(ext_symc_update, ret);
292 crypto_mem_close(&mem_out);
293 crypto_mem_close(&mem_in);
294 return ret;
295 }
296
297 crypto_mem_close(&mem_out);
298 crypto_mem_close(&mem_in);
299 hi_log_func_exit();
300 return ret;
301 }
302 #endif
303