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