1 /* Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
2
3 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
4 * the the People's Republic of China and other countries.
5 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
6
7 * DISCLAIMER
8 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
9 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
10 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
11 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
12 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
13 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
14 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
15
16
17 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
18 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
19 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
20 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
21 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <interrupt.h>
35 #include <hal_cache.h>
36 #include <hal_mem.h>
37 #include <hal_osal.h>
38 #include <hal_sem.h>
39 #include <hal_timer.h>
40 #include <sunxi_hal_ce.h>
41 #include "ce_common.h"
42 #include "hal_ce.h"
43 #include "ce_reg.h"
44 #include "platform_ce.h"
45
46 //#define CE_NO_IRQ
47 #define CE_WAIT_TIME (50000)
48
49 #ifndef CE_NO_IRQ
50 static hal_sem_t ce_sem;
51 #endif
52 //static rt_wqueue_t ce_wqueue;
53
ce_print_hex(char * _data,int _len,void * _addr)54 void ce_print_hex(char *_data, int _len, void *_addr)
55 {
56 int i, j;
57 char last[128] = {0};
58
59 CE_DBG("---------------- The valid len = %d ----------------\n",
60 _len);
61 for (i = 0; i < _len/8; i++) {
62 CE_DBG("%p: %02X %02X %02X %02X %02X %02X %02X %02X\n",
63 i*8 + _addr,
64 _data[i*8+0], _data[i*8+1], _data[i*8+2], _data[i*8+3],
65 _data[i*8+4], _data[i*8+5], _data[i*8+6], _data[i*8+7]);
66 }
67 for (j = 0; j < _len%8; j++) {
68 if (j == 0)
69 snprintf(last, 12, "%p:", i * 8 + _addr);
70 snprintf(last + 11 + j*3, 4, " %02X", _data[i*8 + j]);
71 if (j == _len % 8 - 1)
72 CE_DBG("%s\n", last);
73 }
74 CE_DBG("----------------------------------------------------\n");
75 }
76
ce_print_task_info(ce_task_desc_t * task)77 void ce_print_task_info(ce_task_desc_t *task)
78 {
79 CE_DBG("-----------task_info------\n");
80 CE_DBG("task = 0x%lx\n", (uint32_t)task);
81 CE_DBG("task->comm_ctl = 0x%lx\n", task->comm_ctl);
82 CE_DBG("task->sym_ctl = 0x%lx\n", task->sym_ctl);
83 CE_DBG("task->asym_ctl = 0x%lx\n", task->asym_ctl);
84 CE_DBG("task->chan_id = 0x%lx\n", task->chan_id);
85 CE_DBG("task->ctr_addr = 0x%lx\n", task->ctr_addr);
86 CE_DBG("task->data_len = 0x%lx\n", task->data_len);
87 CE_DBG("task->iv_addr = 0x%lx\n", task->iv_addr);
88 CE_DBG("task->key_addr = 0x%lx\n", task->key_addr);
89 CE_DBG("task->src[0].addr = 0x%lx\n", task->src[0].addr);
90 CE_DBG("task->src[0].len = 0x%lx\n", task->src[0].len);
91 CE_DBG("task->dst[0].addr = 0x%lx\n", task->dst[0].addr);
92 CE_DBG("task->dst[0].len = 0x%lx\n", task->dst[0].len);
93 }
94
95 #ifndef CE_NO_IRQ
ce_irq_handler(void * data)96 static hal_irqreturn_t ce_irq_handler(void *data)
97 {
98 int i;
99 int ret;
100 int pending = 0;
101
102 pending = hal_ce_pending_get();
103 for (i = 0; i < CE_FLOW_NUM; i++) {
104 if (pending & (CE_CHAN_PENDING << i)) {
105 CE_DBG("Chan %d completed. pending: %#x\n", i, pending);
106 hal_ce_pending_clear(i);
107 ret = hal_sem_post(ce_sem);
108 if (ret == 0) {
109 ;
110 } else {
111 CE_ERR("hal_sem_post FAIL \n");
112 }
113 #if 0
114 rt_wqueue_wakeup(&ce_wqueue, NULL);
115 #endif
116 }
117 }
118
119 return HAL_IRQ_OK;
120 }
121
ce_irq_request(void)122 static int ce_irq_request(void)
123 {
124 #ifdef CONFIG_ARCH_SUN20IW2P1
125 uint32_t irqn = SUNXI_IRQ_CE_NS;
126
127 if (hal_request_irq(irqn, ce_irq_handler, "ce", NULL) < 0) {
128 CE_ERR("request irq error\n");
129 return -1;
130 }
131
132 hal_enable_irq(irqn);
133 #else
134 uint32_t irqn = SUNXI_IRQ_CE;
135
136 if (request_irq(irqn, ce_irq_handler, 0, "crypto", NULL) < 0) {
137 CE_ERR("Cannot request IRQ\n");
138 return -1;
139 }
140
141 enable_irq(irqn);
142 #endif
143
144 return 0;
145 }
146 #endif
147
sunxi_ce_init(void)148 int sunxi_ce_init(void)
149 {
150 int ret = 0;
151
152 hal_ce_clock_init();
153 #ifndef CE_NO_IRQ
154 ret = ce_irq_request();
155 if (ret < 0) {
156 return -1;
157 }
158
159 ce_sem = hal_sem_create(0);
160 if (ce_sem == NULL) {
161 CE_ERR("hal_sem_create fail\n");
162 return -1;
163 }
164 #endif
165
166 #if 0
167 rt_wqueue_init(&ce_wqueue);
168 #endif
169
170 return 0;
171 }
172
sunxi_ce_uninit(void)173 int sunxi_ce_uninit(void)
174 {
175 #ifndef CE_NO_IRQ
176 if (ce_sem)
177 hal_sem_delete(ce_sem);
178
179 #ifdef CONFIG_ARCH_SUN20IW2P1
180 hal_free_irq(SUNXI_IRQ_CE_NS);
181 #else
182 hal_free_irq(SUNXI_IRQ_CE);
183 #endif
184 #endif
185
186 return 0;
187 }
188
ce_task_desc_init(ce_task_desc_t * task,uint32_t flow)189 static void ce_task_desc_init(ce_task_desc_t *task, uint32_t flow)
190 {
191 memset((void *)task, 0x0, sizeof(ce_task_desc_t));
192 task->chan_id = flow;
193 hal_ce_task_enable(task);
194 }
195
ce_aes_config(uint32_t dir,uint32_t type,uint32_t mode,uint8_t * key_buf,uint32_t key_length)196 static ce_task_desc_t *ce_aes_config(uint32_t dir, uint32_t type, uint32_t mode,
197 uint8_t *key_buf, uint32_t key_length)
198 {
199 ce_task_desc_t *task = NULL;
200 uint32_t flow = 1;
201
202 task = (ce_task_desc_t *)hal_malloc(sizeof(ce_task_desc_t));
203 if (task == NULL) {
204 CE_ERR("hal_malloc fail\n");
205 return NULL;
206 }
207
208 ce_task_desc_init(task, flow);
209 hal_ce_method_set(dir, type, task);
210 hal_ce_aes_mode_set(mode, task);
211 hal_ce_key_set(key_buf, key_length, task);
212 hal_dcache_clean((unsigned long)key_buf, key_length);
213
214 return task;
215 }
216
ce_aes_sw_padding(crypto_aes_req_ctx_t * ctx)217 static uint32_t ce_aes_sw_padding(crypto_aes_req_ctx_t *ctx)
218 {
219 uint32_t blk_num = 0;
220 uint32_t padding_size = 0;
221 uint32_t last_blk_size = 0;
222
223 blk_num = ctx->src_length / AES_BLOCK_SIZE;
224 last_blk_size = ctx->src_length % AES_BLOCK_SIZE;
225
226 if (last_blk_size) {
227 padding_size = AES_BLOCK_SIZE - last_blk_size;
228 memcpy(ctx->padding, ctx->src_buffer + blk_num * AES_BLOCK_SIZE, last_blk_size);
229 memset(ctx->padding + last_blk_size, padding_size, padding_size);
230 ctx->padding_len = AES_BLOCK_SIZE;
231 } else {
232 ctx->padding_len = 0;
233 }
234
235 return blk_num * AES_BLOCK_SIZE;
236 }
237
ce_aes_start(crypto_aes_req_ctx_t * req_ctx)238 static int ce_aes_start(crypto_aes_req_ctx_t *req_ctx)
239 {
240 int ret = 0;
241 ce_task_desc_t *task;
242 uint32_t src_len = 0;
243 uint32_t src_word_len = 0;
244
245 src_len = ce_aes_sw_padding(req_ctx);
246 src_word_len = src_len >> 2;
247
248 /*ce task config*/
249
250 task = ce_aes_config(req_ctx->dir, CE_METHOD_AES, req_ctx->mode, req_ctx->key, req_ctx->key_length);
251 if (task == NULL) {
252 CE_ERR("ce_aes_config fail\n");
253 return HAL_AES_INPUT_ERROR;
254 }
255
256 hal_ce_pending_clear(task->chan_id);
257
258 if (req_ctx->iv) {
259 hal_ce_iv_set(req_ctx->iv, AES_BLOCK_SIZE, task);
260 hal_dcache_clean((unsigned long)req_ctx->iv, AES_BLOCK_SIZE);
261 }
262 if (CE_AES_MODE_CTR == req_ctx->mode) {
263 hal_ce_cnt_set(req_ctx->iv_next, req_ctx->key_length, task);
264 hal_dcache_clean((unsigned long)req_ctx->iv_next, req_ctx->key_length);
265 } else if (CE_AES_MODE_CTS == req_ctx->mode) {
266 hal_ce_cts_last(task);
267 } else if (CE_AES_MODE_CFB == req_ctx->mode) {
268 hal_ce_cfb_bitwidth_set(req_ctx->bitwidth,task);
269 }
270
271 if ((task->sym_ctl & 0xF00) == (CE_AES_MODE_CTS << CE_SYM_CTL_OP_MODE_SHIFT))
272 task->data_len = src_len + req_ctx->padding_len;
273 else
274 hal_ce_data_len_set(src_len + req_ctx->padding_len, task);
275
276 if (src_len) {
277 task->src[0].addr = (uint32_t)__va_to_pa((unsigned long)req_ctx->src_buffer);
278 task->src[0].len = src_word_len;
279
280 if (req_ctx->padding_len) {
281 task->src[1].addr = (uint32_t)__va_to_pa((unsigned long)req_ctx->padding);
282 task->src[1].len = req_ctx->padding_len >> 2;
283 }
284 } else {
285 task->src[0].addr = (uint32_t)__va_to_pa((unsigned long)req_ctx->padding);
286 task->src[0].len = req_ctx->padding_len >> 2;
287 }
288
289 task->dst[0].addr = (uint32_t)__va_to_pa((unsigned long)req_ctx->dst_buffer);
290 task->dst[0].len = (src_len + req_ctx->padding_len) >> 2;
291
292 task->next = 0;
293 hal_dcache_clean((unsigned long)task, sizeof(ce_task_desc_t));
294 if (src_len) {
295 hal_dcache_clean((unsigned long)req_ctx->src_buffer, src_len);
296 }
297 if (req_ctx->padding_len) {
298 hal_dcache_clean((unsigned long)req_ctx->padding, req_ctx->padding_len);
299 }
300 hal_dcache_clean((unsigned long)req_ctx->dst_buffer, src_len + req_ctx->padding_len);
301 //ce_print_task_info(task);
302 hal_ce_set_task((unsigned long)task);
303 hal_ce_irq_enable(task->chan_id);
304 hal_ce_ctrl_start();
305
306 #ifdef CE_NO_IRQ
307 hal_ce_wait_finish(task->chan_id);
308 hal_ce_pending_clear(task->chan_id);
309 #else
310 #if 1
311 ret = hal_sem_timedwait(ce_sem, CE_WAIT_TIME);
312 if (ret != 0) {
313 CE_ERR("Timed out\n");
314 hal_free(task);
315 return HAL_AES_TIME_OUT;
316 }
317 #else
318 rt_wqueue_wait(&ce_wqueue, 0, RT_WAITING_FOREVER);
319 #endif
320 #endif
321
322 hal_dcache_invalidate((uint32_t)req_ctx->dst_buffer, src_len + req_ctx->padding_len);
323
324 hal_ce_irq_disable(task->chan_id);
325
326 if (hal_ce_get_erro() > 0) {
327 CE_ERR("error\n");
328 hal_ce_reg_printf();
329 hal_free(task);
330 return HAL_AES_CRYPTO_ERROR;
331 }
332
333 CE_DBG("do_aes_crypto sucess\n");
334 hal_free(task);
335 return HAL_AES_STATUS_OK;
336 }
337
ce_aes_check_ctx_vaild(crypto_aes_req_ctx_t * req_ctx)338 static int ce_aes_check_ctx_vaild(crypto_aes_req_ctx_t *req_ctx)
339 {
340 if (req_ctx == NULL) {
341 CE_ERR("aes req_ctx is NULL\n");
342 return HAL_AES_INPUT_ERROR;
343 }
344
345 if ((req_ctx->src_buffer == NULL)
346 || (req_ctx->dst_buffer == NULL)
347 || (req_ctx->key == NULL)
348 || ((req_ctx->mode != CE_AES_MODE_ECB) && (req_ctx->iv == NULL) )) {
349 CE_ERR("input is NULL\n");
350 return HAL_AES_INPUT_ERROR;
351 }
352
353 if ((req_ctx->key_length != AES_KEYSIZE_16)
354 && (req_ctx->key_length != AES_KEYSIZE_24)
355 && (req_ctx->key_length != AES_KEYSIZE_32)) {
356 CE_ERR("key length is %ld, invalid\n", req_ctx->key_length);
357 return HAL_AES_INPUT_ERROR;
358 }
359
360 if ((((u32)req_ctx->src_buffer & (CE_ALIGN_SIZE - 1)) != 0)
361 || (((u32)req_ctx->dst_buffer & (CE_ALIGN_SIZE - 1)) != 0)
362 || (((u32)req_ctx->key & (CE_ALIGN_SIZE - 1)) != 0)) {
363 CE_ERR("input buffer is not %d align\n", CE_ALIGN_SIZE);
364 return HAL_AES_INPUT_ERROR;
365 }
366
367 if (req_ctx->dir == CE_DIR_DECRYPT) {
368 if (((req_ctx->mode == CE_AES_MODE_ECB)
369 || (req_ctx->mode == CE_AES_MODE_CBC)
370 || (req_ctx->mode == CE_AES_MODE_CTS))
371 && (req_ctx->src_length % AES_BLOCK_SIZE != 0)) {
372 CE_ERR("src_length: %d is not %d align\n",
373 req_ctx->src_length, AES_BLOCK_SIZE);
374 return HAL_AES_INPUT_ERROR;
375 }
376 if (req_ctx->src_length > req_ctx->dst_length) {
377 CE_ERR("src_length: %d should not bigger than dst_length: %d\n",
378 req_ctx->src_length, req_ctx->dst_length);
379 return HAL_AES_INPUT_ERROR;
380 }
381 } else if (req_ctx->dir == CE_DIR_ENCRYPT) {
382 if (req_ctx->dst_length < CE_ROUND_UP(req_ctx->src_length, AES_BLOCK_SIZE)) {
383 CE_ERR("dst_length: %d should not smaller than %d\n",
384 req_ctx->dst_length,
385 CE_ROUND_UP(req_ctx->src_length, AES_BLOCK_SIZE));
386 return HAL_AES_INPUT_ERROR;
387 }
388 } else {
389 CE_ERR("input crypt dir: %d is error.\n", req_ctx->dir);
390 return HAL_AES_INPUT_ERROR;
391 }
392
393 return HAL_AES_STATUS_OK;
394 }
395
do_aes_crypto(crypto_aes_req_ctx_t * req_ctx)396 int do_aes_crypto(crypto_aes_req_ctx_t *req_ctx)
397 {
398 uint32_t last_block_size = 0;
399 uint32_t block_num = 0;
400 uint32_t padding_size = 0;
401 uint32_t first_encypt_size = 0;
402 uint8_t data_block[AES_BLOCK_SIZE] = {0};
403 uint8_t *iv;
404 uint8_t *init_vector2;
405 ce_task_desc_t *task;
406 int ret;
407
408 ret = ce_aes_check_ctx_vaild(req_ctx);
409 if (ret) {
410 CE_ERR("ce_aes_check_ctx_vaild fail\n");
411 return ret;
412 }
413
414 ret = ce_aes_start(req_ctx);
415 if (ret < 0) {
416 CE_ERR("aes crypto fail\n");
417 return ret;
418 }
419
420 return ret;
421 }
422
ce_hash_endian4(uint32_t data)423 static uint32_t ce_hash_endian4(uint32_t data)
424 {
425 uint32_t d1, d2, d3, d4;
426
427 d1 = (data & 0xff) << 24;
428 d2 = (data & 0xff00) << 8;
429 d3 = (data & 0xff0000) >> 8;
430 d4 = (data & 0xff000000) >> 24;
431
432 return (d1 | d2 | d3 | d4);
433 }
434
ce_hash_blk_size(int type)435 static uint32_t ce_hash_blk_size(int type)
436 {
437 if ((type == CE_METHOD_SHA384) || (type == CE_METHOD_SHA512))
438 return SHA512_BLOCK_SIZE;
439 return SHA1_BLOCK_SIZE;
440 }
441
ce_hash_sw_padding(crypto_hash_req_ctx_t * ctx)442 static uint32_t ce_hash_sw_padding(crypto_hash_req_ctx_t *ctx)
443 {
444 uint32_t blk_size = ce_hash_blk_size(ctx->type);
445 uint32_t len_threshold = (blk_size == SHA512_BLOCK_SIZE) ? 112 : 56;
446 uint32_t n = ctx->src_length % blk_size;
447 uint8_t *p = ctx->padding;
448 uint32_t len_l = ctx->src_length << 3; /* total len, in bits. */
449 uint32_t len_h = ctx->src_length >> 29;
450 uint32_t big_endian = (ctx->type == CE_METHOD_MD5) ? 0 : 1;
451
452 memset(ctx->padding, 0, 256);
453
454 if (n) {
455 memcpy(ctx->padding, ctx->src_buffer + ctx->src_length - n, n);
456 }
457
458 CE_DBG("ctx->type = %d, n = %d, ctx->src_length = %d\n", ctx->type, n, ctx->src_length);
459 p[n] = 0x80;
460 n++;
461
462 if (n > len_threshold) { /* The pad data need two blocks. */
463 memset(p+n, 0, blk_size*2 - n);
464 p += blk_size*2 - 8;
465 } else {
466 memset(p+n, 0, blk_size - n);
467 p += blk_size - 8;
468 }
469
470 if (big_endian == 1) {
471 #if 0
472 /* The length should use bit64 in SHA384/512 case.
473 * The OpenSSL package is always small than 8K,
474 * so we use still bit32.
475 */
476 if (blk_size == SHA512_BLOCK_SIZE) {
477 int len_hh = ctx->cnt >> 61;
478 *(int *)(p-4) = ce_hash_endian4(len_hh);
479 }
480 #endif
481 *(int *)p = ce_hash_endian4(len_h);
482 *(int *)(p+4) = ce_hash_endian4(len_l);
483 } else {
484 *(int *)p = len_l;
485 *(int *)(p+4) = len_h;
486 }
487
488 ctx->padding_len = (uint32_t)(p + 8 - ctx->padding);
489
490 CE_DBG("After padding %d: %02x %02x %02x %02x %02x %02x %02x %02x\n",
491 ctx->padding_len,
492 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
493
494 return ctx->src_length - (ctx->src_length % blk_size);
495 }
496
ce_hash_start(crypto_hash_req_ctx_t * req_ctx)497 static int ce_hash_start(crypto_hash_req_ctx_t *req_ctx)
498 {
499 int ret = 0;
500 int i = 0;
501 uint8_t chan_id = 1;
502 ce_task_desc_t *task = NULL;
503 uint32_t src_word_len = 0;
504 uint32_t src_length = ce_hash_sw_padding(req_ctx);
505
506 src_word_len = src_length >> 2;
507
508 task = (ce_task_desc_t *)hal_malloc(sizeof(ce_task_desc_t));
509 if (task == NULL) {
510 CE_ERR("hal_malloc fail\n");
511 return HAL_HASH_MALLOC_ERROR;
512 }
513 CE_DBG("task addr = 0x%lx\n", (uint32_t)task);
514
515 ce_task_desc_init(task, chan_id);
516 hal_ce_pending_clear(chan_id);
517 hal_ce_method_set(req_ctx->dir, req_ctx->type, task);
518 hal_ce_data_len_set(src_length + req_ctx->padding_len, task);
519 if (req_ctx->md_size) {
520 hal_ce_iv_set(req_ctx->md, req_ctx->md_size, task);
521 hal_dcache_clean((unsigned long)req_ctx->md, req_ctx->md_size);
522 hal_ce_iv_mode_set(CE_HASH_IV_INPUT, task);
523 }
524
525 if (src_word_len != 0) {
526 task->src[0].addr = (uint32_t)__va_to_pa((uint32_t)req_ctx->src_buffer);
527 task->src[0].len = src_word_len;
528 task->src[1].addr = (uint32_t)__va_to_pa((uint32_t)req_ctx->padding);
529 task->src[1].len = req_ctx->padding_len >> 2;
530 } else {
531 task->src[0].addr = (uint32_t)__va_to_pa((uint32_t)req_ctx->padding);
532 task->src[0].len = req_ctx->padding_len >> 2;
533 }
534 task->dst[0].addr = (uint32_t)__va_to_pa((uint32_t)req_ctx->dst_buffer);
535 task->dst[0].len = req_ctx->dst_length >> 2;
536 task->next = 0;
537
538 hal_dcache_clean((uint32_t)task, sizeof(ce_task_desc_t));
539 hal_dcache_clean((uint32_t)req_ctx->src_buffer, req_ctx->src_length);
540 hal_dcache_clean((uint32_t)req_ctx->padding, req_ctx->padding_len);
541 hal_dcache_clean((uint32_t)req_ctx->dst_buffer, req_ctx->dst_length);
542 //FlushCacheAll();
543 //ce_print_task_info(task);
544 hal_ce_set_task((uint32_t)task);
545 hal_ce_irq_enable(task->chan_id);
546 hal_ce_ctrl_start();
547
548 #ifdef CE_NO_IRQ
549 hal_ce_wait_finish(task->chan_id);
550 hal_ce_pending_clear(task->chan_id);
551 #else
552 ret = hal_sem_timedwait(ce_sem, CE_WAIT_TIME);
553 if (ret != 0) {
554 CE_ERR("Timed out\n");
555 ret = HAL_HASH_TIME_OUT;
556 goto fail;
557 }
558 #endif
559 hal_dcache_invalidate((uint32_t)req_ctx->dst_buffer, req_ctx->dst_length);
560
561 if (hal_ce_get_erro() > 0) {
562 hal_ce_reg_printf();
563 ret = HAL_HASH_CRYPTO_ERROR;
564 goto fail;
565 }
566 //ce_print_hex((char *)task->dst[0].addr, (task->dst[0].len * 4), (char *)task->dst[0].addr);
567 //hal_ce_reg_printf();
568
569 hal_ce_irq_disable(task->chan_id);
570 memcpy(req_ctx->md, req_ctx->dst_buffer, req_ctx->dst_length);
571 req_ctx->md_size = req_ctx->dst_length;
572 hal_free(task);
573
574 return HAL_HASH_STATUS_OK;
575
576 fail:
577 if (task) {
578 hal_free(task);
579 }
580 return ret;
581 }
582
ce_hash_check_ctx_valid(crypto_hash_req_ctx_t * req_ctx)583 static int ce_hash_check_ctx_valid(crypto_hash_req_ctx_t *req_ctx)
584 {
585 if (req_ctx == NULL) {
586 CE_ERR("sha req_ctx is NULL\n");
587 return HAL_HASH_INPUT_ERROR;
588 }
589
590 if ((((u32)req_ctx->dst_buffer & (CE_ALIGN_SIZE - 1)) != 0)
591 || (((u32)req_ctx->src_buffer & (CE_ALIGN_SIZE - 1)) != 0)) {
592 CE_ERR("input buffer addr is not %d align\n", CE_ALIGN_SIZE);
593 return HAL_HASH_INPUT_ERROR;
594 }
595
596 if (req_ctx->type == CE_METHOD_MD5) {
597 if ((req_ctx->dst_length != MD5_DIGEST_SIZE)
598 || ((req_ctx->md_size != 0)
599 && (req_ctx->md_size != MD5_DIGEST_SIZE))) {
600 CE_ERR("output length is not %d\n", MD5_DIGEST_SIZE);
601 return HAL_HASH_INPUT_ERROR;
602 }
603 } else if (req_ctx->type == CE_METHOD_SHA1) {
604 if ((req_ctx->dst_length != SHA1_DIGEST_SIZE)
605 || ((req_ctx->md_size != 0)
606 && (req_ctx->md_size != SHA1_DIGEST_SIZE))) {
607 CE_ERR("output length is not %d\n", SHA1_DIGEST_SIZE);
608 return HAL_HASH_INPUT_ERROR;
609 }
610 } else if (req_ctx->type == CE_METHOD_SHA224) {
611 if ((req_ctx->dst_length != SHA256_DIGEST_SIZE)
612 || ((req_ctx->md_size != 0)
613 && (req_ctx->md_size != SHA256_DIGEST_SIZE))) {
614 CE_ERR("output length is not %d\n", SHA256_DIGEST_SIZE);
615 return HAL_HASH_INPUT_ERROR;
616 }
617 } else if (req_ctx->type == CE_METHOD_SHA256) {
618 if ((req_ctx->dst_length != SHA256_DIGEST_SIZE)
619 || ((req_ctx->md_size != 0)
620 && (req_ctx->md_size != SHA256_DIGEST_SIZE))) {
621 CE_ERR("output length is not %d\n", SHA256_DIGEST_SIZE);
622 return HAL_HASH_INPUT_ERROR;
623 }
624 } else if (req_ctx->type == CE_METHOD_SHA384) {
625 if ((req_ctx->dst_length != SHA512_DIGEST_SIZE)
626 || ((req_ctx->md_size != 0)
627 && (req_ctx->md_size != SHA512_DIGEST_SIZE))) {
628 CE_ERR("output length is not %d\n", SHA512_DIGEST_SIZE);
629 return HAL_HASH_INPUT_ERROR;
630 }
631 } else if (req_ctx->type == CE_METHOD_SHA512) {
632 if ((req_ctx->dst_length != SHA512_DIGEST_SIZE)
633 || ((req_ctx->md_size != 0)
634 && (req_ctx->md_size != SHA512_DIGEST_SIZE))) {
635 CE_ERR("output length is not %d\n", SHA512_DIGEST_SIZE);
636 return HAL_HASH_INPUT_ERROR;
637 }
638 } else {
639 CE_ERR("ce don't support hash mode: %d\n", req_ctx->type);
640 return HAL_HASH_INPUT_ERROR;
641 }
642
643 return HAL_HASH_STATUS_OK;
644 }
645
do_hash_crypto(crypto_hash_req_ctx_t * req_ctx)646 int do_hash_crypto(crypto_hash_req_ctx_t *req_ctx)
647 {
648 uint8_t *src_tmp = NULL;
649 uint32_t src_align_len = 0;
650 int ret = 0;
651
652 ret = ce_hash_check_ctx_valid(req_ctx);
653 if (ret < 0) {
654 CE_ERR("ce_hash_check_ctx_valid fail: %d\n", ret);
655 return ret;
656 }
657
658 ret = ce_hash_start(req_ctx);
659 if (ret < 0) {
660 CE_ERR("caclu hash erro num is %d\n", ret);
661 return HAL_HASH_CRYPTO_ERROR;
662 }
663
664 return HAL_HASH_STATUS_OK;
665 }
666
ce_rsa_sw_padding(uint8_t * dst_buf,uint8_t * src_buf,uint32_t data_len,uint32_t group_len)667 static void ce_rsa_sw_padding(uint8_t *dst_buf, uint8_t *src_buf, uint32_t data_len, uint32_t group_len)
668 {
669 int i = 0;
670
671 memset(dst_buf, 0, group_len);
672 for (i = group_len - data_len; i < group_len; i++) {
673 dst_buf[i] = src_buf[group_len - 1 - i];
674 }
675 }
676
ce_rsa_start(crypto_rsa_req_ctx_t * req_ctx)677 static int ce_rsa_start(crypto_rsa_req_ctx_t *req_ctx)
678 {
679 int ret = 0;
680 uint8_t chan_id = 2;
681 uint8_t *p_src = NULL;
682 uint8_t *p_n = NULL;
683 uint8_t *p_d = NULL;
684 uint8_t *p_dst = NULL;
685 ce_task_desc_t *task = NULL;
686 uint32_t bitwidth_byte_len = 0;
687 uint32_t bitwidth_word_len = 0;
688
689 bitwidth_byte_len = req_ctx->bitwidth >> 3;
690 bitwidth_word_len = req_ctx->bitwidth >> 5;
691
692 p_src = hal_malloc(bitwidth_byte_len);
693 if (p_src == NULL) {
694 CE_ERR("rsa src hal_malloc fail\n");
695 ret = HAL_RSA_MALLOC_ERROR;
696 goto fail;
697 }
698 memset(p_src, 0x0, bitwidth_byte_len);
699 ce_rsa_sw_padding(p_src, req_ctx->src_buffer, req_ctx->src_length, bitwidth_byte_len);
700
701 p_n = hal_malloc(bitwidth_byte_len);
702 if (p_n == NULL) {
703 CE_ERR("rsa key n hal_malloc fail\n");
704 ret = HAL_RSA_MALLOC_ERROR;
705 goto fail;
706 }
707 memset(p_n, 0x0, bitwidth_byte_len);
708 ce_rsa_sw_padding(p_n, req_ctx->key_n, req_ctx->n_len, bitwidth_byte_len);
709
710 if (req_ctx->key_d) {
711 p_d = hal_malloc(bitwidth_byte_len);
712 if (p_d == NULL) {
713 CE_ERR("rsa key d hal_malloc fail\n");
714 ret = HAL_RSA_MALLOC_ERROR;
715 goto fail;
716 }
717 memset(p_d, 0x0, bitwidth_byte_len);
718 ce_rsa_sw_padding(p_d, req_ctx->key_d, req_ctx->d_len, bitwidth_byte_len);
719 req_ctx->key_d = p_d;
720 }
721
722 p_dst = hal_malloc(bitwidth_byte_len);
723 if (p_dst == NULL) {
724 CE_ERR("hal_malloc fail\n");
725 ret = HAL_RSA_MALLOC_ERROR;
726 goto fail;
727 }
728 memset(p_dst, 0x0, bitwidth_byte_len);
729
730 task = (ce_task_desc_t *)hal_malloc(sizeof(ce_task_desc_t));
731 if (task == NULL) {
732 CE_ERR("rt_malloc_align fail\n");
733 ret = HAL_RSA_MALLOC_ERROR;
734 goto fail;
735 }
736 CE_DBG("task addr = 0x%lx\n", (uint32_t)task);
737
738 ce_task_desc_init(task, chan_id);
739 hal_ce_pending_clear(chan_id);
740 hal_ce_method_set(req_ctx->dir, req_ctx->type, task);
741 hal_ce_rsa_width_set(req_ctx->bitwidth, task);
742 task->iv_addr = (uint32_t)__va_to_pa((uint32_t)p_n);
743 if (req_ctx->key_d)
744 task->key_addr = (uint32_t)__va_to_pa((uint32_t)p_d);
745 else
746 task->key_addr = (uint32_t)__va_to_pa((uint32_t)req_ctx->key_e);
747
748 hal_ce_data_len_set(bitwidth_byte_len, task);
749
750 task->src[0].addr = (uint32_t)__va_to_pa((uint32_t)p_src);
751 task->src[0].len = bitwidth_word_len;
752
753 task->dst[0].addr = (uint32_t)__va_to_pa((uint32_t)p_dst);
754 task->dst[0].len = bitwidth_word_len;
755 task->next = 0;
756
757 hal_dcache_clean((uint32_t)task, sizeof(ce_task_desc_t));
758 hal_dcache_clean((uint32_t)p_src, bitwidth_byte_len);
759 hal_dcache_clean((uint32_t)p_n, bitwidth_byte_len);
760 if (req_ctx->key_d)
761 hal_dcache_clean((uint32_t)p_d, bitwidth_byte_len);
762 else
763 hal_dcache_clean((uint32_t)req_ctx->key_e, bitwidth_byte_len);
764 hal_dcache_clean((uint32_t)p_dst, bitwidth_byte_len);
765
766 //FlushCacheAll();
767 /*ce_print_task_info(task);*/
768 hal_ce_set_task((uint32_t)task);
769 hal_ce_irq_enable(task->chan_id);
770 hal_ce_ctrl_start();
771
772 #ifdef CE_NO_IRQ
773 hal_ce_wait_finish(task->chan_id);
774 hal_ce_pending_clear(task->chan_id);
775 #else
776 ret = hal_sem_timedwait(ce_sem, CE_WAIT_TIME);
777 if (ret != 0) {
778 CE_ERR("Timed out\n");
779 ret = HAL_RSA_CRYPTO_ERROR;
780 goto fail;
781 }
782 #endif
783
784 hal_dcache_invalidate((uint32_t)p_dst, bitwidth_byte_len);
785
786 /*ce_reg_printf();*/
787 if (hal_ce_get_erro() > 0) {
788 hal_ce_reg_printf();
789 ret = HAL_RSA_CRYPTO_ERROR;
790 goto fail;
791 }
792
793 hal_ce_irq_disable(task->chan_id);
794
795 ce_rsa_sw_padding(req_ctx->dst_buffer, p_dst, req_ctx->dst_length, req_ctx->dst_length);
796
797 fail:
798 if (p_src)
799 hal_free(p_src);
800
801 if (p_n)
802 hal_free(p_n);
803
804 if (p_d)
805 hal_free(p_d);
806
807 if (p_dst)
808 hal_free(p_dst);
809
810 if (task)
811 hal_free(task);
812
813 return ret;
814 }
815
ce_rsa_check_ctx_valid(crypto_rsa_req_ctx_t * req_ctx)816 static int ce_rsa_check_ctx_valid(crypto_rsa_req_ctx_t *req_ctx)
817 {
818 if (req_ctx == NULL) {
819 CE_ERR("rsa req_ctx is NULL\n");
820 return HAL_RSA_INPUT_ERROR;
821 }
822
823 if ((((u32)req_ctx->key_n & (CE_ALIGN_SIZE - 1)) != 0)
824 || (((u32)req_ctx->key_e & (CE_ALIGN_SIZE - 1)) != 0)
825 || (((u32)req_ctx->key_d & (CE_ALIGN_SIZE - 1)) != 0)
826 || (((u32)req_ctx->src_buffer & (CE_ALIGN_SIZE - 1)) != 0)
827 || (((u32)req_ctx->dst_buffer & (CE_ALIGN_SIZE - 1)) != 0)) {
828 printf("rsa req_ctx buffer is not %d align\n", CE_ALIGN_SIZE);
829 return HAL_RSA_INPUT_ERROR;
830 }
831
832 if ((req_ctx->bitwidth == 512)
833 || (req_ctx->bitwidth == 1024)
834 || (req_ctx->bitwidth == 2048)) {
835 if ((req_ctx->n_len > req_ctx->bitwidth / 8)
836 || (req_ctx->e_len > req_ctx->bitwidth / 8)
837 || (req_ctx->d_len > req_ctx->bitwidth / 8)
838 || (req_ctx->src_length > req_ctx->bitwidth / 8)
839 || (req_ctx->dst_length > req_ctx->bitwidth / 8)) {
840 CE_ERR("rsa length should not bigger than %d\n", req_ctx->bitwidth / 8);
841 return HAL_RSA_INPUT_ERROR;
842 }
843 } else {
844 CE_ERR("invalid bitwidth: %d\n", req_ctx->bitwidth);
845 return HAL_RSA_INPUT_ERROR;
846 }
847
848 return HAL_RSA_STATUS_OK;
849 }
850
do_rsa_crypto(crypto_rsa_req_ctx_t * req_ctx)851 int do_rsa_crypto(crypto_rsa_req_ctx_t *req_ctx)
852 {
853 int ret = 0;
854
855 ret = ce_rsa_check_ctx_valid(req_ctx);
856 if (ret < 0) {
857 CE_ERR("ce_rsa_check_ctx_valid fail: %d\n", ret);
858 return ret;
859 }
860
861 ret = ce_rsa_start(req_ctx);
862 if (ret < 0) {
863 CE_ERR("calc rsa erro num is %d\n", ret);
864 return ret;
865 }
866
867 return HAL_RSA_STATUS_OK;
868 }
869
do_rng_gen(crypto_rng_req_ctx_t * req_ctx)870 int do_rng_gen(crypto_rng_req_ctx_t *req_ctx)
871 {
872 int ret = 0;
873 uint8_t chan_id = 2;
874 uint32_t dst_len = 0;
875 uint8_t *dst_buf = NULL;
876 ce_task_desc_t *task = NULL;
877
878 if (req_ctx->mode == CE_METHOD_TRNG) {
879 dst_len = CE_ROUND_UP(req_ctx->rng_len, 32); /*align with 32 Bytes*/
880 } else if (req_ctx->mode == CE_METHOD_PRNG) {
881 dst_len = CE_ROUND_UP(req_ctx->rng_len, 20); /*align with 20 Bytes*/
882 } else {
883 CE_ERR("Error: do not support mode %d\n", req_ctx->mode);
884 ret = HAL_RNG_INPUT_ERROR;
885 goto fail;
886 }
887
888 if (dst_len > SS_RNG_MAX_LEN) {
889 CE_ERR("Error: The RNG length is too large: %d\n", dst_len);
890 ret = HAL_RNG_INPUT_ERROR;
891 goto fail;
892 }
893
894 dst_buf = (uint8_t *)hal_malloc(dst_len);
895 if (dst_buf == NULL) {
896 CE_ERR("hal_malloc dst_buf fail\n");
897 ret = HAL_RNG_MALLOC_ERROR;
898 goto fail;
899 }
900
901 task = (ce_task_desc_t *)hal_malloc(sizeof(ce_task_desc_t));
902 if (task == NULL) {
903 CE_ERR("hal_malloc task fail\n");
904 ret = HAL_RNG_MALLOC_ERROR;
905 goto fail;
906 }
907
908 CE_DBG("task addr = 0x%lx, rng_buf = 0x%lx, rng_len = %d\n", (uint32_t)task, req_ctx->rng_buf, req_ctx->rng_len);
909
910 ce_task_desc_init(task, chan_id);
911 hal_ce_pending_clear(chan_id);
912 hal_ce_method_set(0, req_ctx->mode, task);
913 hal_ce_data_len_set(dst_len, task);
914
915 if (req_ctx->mode == CE_METHOD_PRNG) {
916 /* must set the seed add in prng */
917 if (req_ctx->key && (req_ctx->key_len == 24)) {
918 hal_ce_key_set(req_ctx->key, req_ctx->key_len, task);
919 hal_dcache_clean((uint32_t)req_ctx->key, req_ctx->key_len);
920 } else {
921 CE_ERR("Error: RRNG must set seed, and the seed size must be 24!\n");
922 ret = HAL_RNG_INPUT_ERROR;
923 goto fail;
924 }
925 }
926
927 task->src[0].addr = 0;
928 task->src[0].len = 0;
929
930 task->dst[0].addr = (uint32_t)__va_to_pa((uint32_t)dst_buf);
931 task->dst[0].len = dst_len >> 2;
932
933 hal_dcache_clean((uint32_t)task, sizeof(ce_task_desc_t));
934 hal_dcache_clean((uint32_t)dst_buf, dst_len);
935
936 //ce_print_task_info(task);
937 hal_ce_set_task((uint32_t)task);
938 hal_ce_irq_enable(task->chan_id);
939 hal_ce_ctrl_start();
940
941 #ifdef CE_NO_IRQ
942 hal_ce_wait_finish(task->chan_id);
943 hal_ce_pending_clear(task->chan_id);
944 #else
945 ret = hal_sem_timedwait(ce_sem, CE_WAIT_TIME);
946 if (ret != 0) {
947 CE_ERR("Timed out\n");
948 ret = HAL_RNG_TIME_OUT;
949 goto fail;
950 }
951 #endif
952 hal_dcache_invalidate((uint32_t)dst_buf, dst_len);
953
954 if (req_ctx->mode == CE_METHOD_PRNG) {
955 hal_dcache_invalidate((uint32_t)req_ctx->key, req_ctx->key_len);
956 }
957
958 if (hal_ce_get_erro() > 0) {
959 hal_ce_reg_printf();
960 ret = HAL_RNG_CRYPTO_ERROR;
961 goto fail;
962 }
963 //ce_print_hex((char *)task->dst[0].addr, (task->dst[0].len * 4), (char *)task->dst[0].addr);
964 /*ce_reg_printf();*/
965
966 memcpy(req_ctx->rng_buf, dst_buf, req_ctx->rng_len);
967
968 hal_ce_irq_disable(task->chan_id);
969
970 hal_free(task);
971 hal_free(dst_buf);
972 return HAL_RNG_STATUS_OK;
973
974 fail:
975 if (task) {
976 hal_free(task);
977 }
978
979 if (dst_buf) {
980 hal_free(task);
981 }
982
983 return ret;
984 }
985