• 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_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