1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/interrupt.h>
17#include <crypto/scatterwalk.h>
18#include <linux/ccp.h>
19
20#include "ccp-dev.h"
21
22
23static const __be32 ccp_sha1_init[CCP_SHA_CTXSIZE / sizeof(__be32)] = {
24 cpu_to_be32(SHA1_H0), cpu_to_be32(SHA1_H1),
25 cpu_to_be32(SHA1_H2), cpu_to_be32(SHA1_H3),
26 cpu_to_be32(SHA1_H4), 0, 0, 0,
27};
28
29static const __be32 ccp_sha224_init[CCP_SHA_CTXSIZE / sizeof(__be32)] = {
30 cpu_to_be32(SHA224_H0), cpu_to_be32(SHA224_H1),
31 cpu_to_be32(SHA224_H2), cpu_to_be32(SHA224_H3),
32 cpu_to_be32(SHA224_H4), cpu_to_be32(SHA224_H5),
33 cpu_to_be32(SHA224_H6), cpu_to_be32(SHA224_H7),
34};
35
36static const __be32 ccp_sha256_init[CCP_SHA_CTXSIZE / sizeof(__be32)] = {
37 cpu_to_be32(SHA256_H0), cpu_to_be32(SHA256_H1),
38 cpu_to_be32(SHA256_H2), cpu_to_be32(SHA256_H3),
39 cpu_to_be32(SHA256_H4), cpu_to_be32(SHA256_H5),
40 cpu_to_be32(SHA256_H6), cpu_to_be32(SHA256_H7),
41};
42
43static u32 ccp_alloc_ksb(struct ccp_device *ccp, unsigned int count)
44{
45 int start;
46
47 for (;;) {
48 mutex_lock(&ccp->ksb_mutex);
49
50 start = (u32)bitmap_find_next_zero_area(ccp->ksb,
51 ccp->ksb_count,
52 ccp->ksb_start,
53 count, 0);
54 if (start <= ccp->ksb_count) {
55 bitmap_set(ccp->ksb, start, count);
56
57 mutex_unlock(&ccp->ksb_mutex);
58 break;
59 }
60
61 ccp->ksb_avail = 0;
62
63 mutex_unlock(&ccp->ksb_mutex);
64
65
66 if (wait_event_interruptible(ccp->ksb_queue, ccp->ksb_avail))
67 return 0;
68 }
69
70 return KSB_START + start;
71}
72
73static void ccp_free_ksb(struct ccp_device *ccp, unsigned int start,
74 unsigned int count)
75{
76 if (!start)
77 return;
78
79 mutex_lock(&ccp->ksb_mutex);
80
81 bitmap_clear(ccp->ksb, start - KSB_START, count);
82
83 ccp->ksb_avail = 1;
84
85 mutex_unlock(&ccp->ksb_mutex);
86
87 wake_up_interruptible_all(&ccp->ksb_queue);
88}
89
90static u32 ccp_gen_jobid(struct ccp_device *ccp)
91{
92 return atomic_inc_return(&ccp->current_id) & CCP_JOBID_MASK;
93}
94
95static void ccp_sg_free(struct ccp_sg_workarea *wa)
96{
97 if (wa->dma_count)
98 dma_unmap_sg(wa->dma_dev, wa->dma_sg, wa->nents, wa->dma_dir);
99
100 wa->dma_count = 0;
101}
102
103static int ccp_init_sg_workarea(struct ccp_sg_workarea *wa, struct device *dev,
104 struct scatterlist *sg, u64 len,
105 enum dma_data_direction dma_dir)
106{
107 memset(wa, 0, sizeof(*wa));
108
109 wa->sg = sg;
110 if (!sg)
111 return 0;
112
113 wa->nents = sg_nents_for_len(sg, len);
114 if (wa->nents < 0)
115 return wa->nents;
116
117 wa->bytes_left = len;
118 wa->sg_used = 0;
119
120 if (len == 0)
121 return 0;
122
123 if (dma_dir == DMA_NONE)
124 return 0;
125
126 wa->dma_sg = sg;
127 wa->dma_dev = dev;
128 wa->dma_dir = dma_dir;
129 wa->dma_count = dma_map_sg(dev, sg, wa->nents, dma_dir);
130 if (!wa->dma_count)
131 return -ENOMEM;
132
133 return 0;
134}
135
136static void ccp_update_sg_workarea(struct ccp_sg_workarea *wa, unsigned int len)
137{
138 unsigned int nbytes = min_t(u64, len, wa->bytes_left);
139
140 if (!wa->sg)
141 return;
142
143 wa->sg_used += nbytes;
144 wa->bytes_left -= nbytes;
145 if (wa->sg_used == wa->sg->length) {
146 wa->sg = sg_next(wa->sg);
147 wa->sg_used = 0;
148 }
149}
150
151static void ccp_dm_free(struct ccp_dm_workarea *wa)
152{
153 if (wa->length <= CCP_DMAPOOL_MAX_SIZE) {
154 if (wa->address)
155 dma_pool_free(wa->dma_pool, wa->address,
156 wa->dma.address);
157 } else {
158 if (wa->dma.address)
159 dma_unmap_single(wa->dev, wa->dma.address, wa->length,
160 wa->dma.dir);
161 kfree(wa->address);
162 }
163
164 wa->address = NULL;
165 wa->dma.address = 0;
166}
167
168static int ccp_init_dm_workarea(struct ccp_dm_workarea *wa,
169 struct ccp_cmd_queue *cmd_q,
170 unsigned int len,
171 enum dma_data_direction dir)
172{
173 memset(wa, 0, sizeof(*wa));
174
175 if (!len)
176 return 0;
177
178 wa->dev = cmd_q->ccp->dev;
179 wa->length = len;
180
181 if (len <= CCP_DMAPOOL_MAX_SIZE) {
182 wa->dma_pool = cmd_q->dma_pool;
183
184 wa->address = dma_pool_alloc(wa->dma_pool, GFP_KERNEL,
185 &wa->dma.address);
186 if (!wa->address)
187 return -ENOMEM;
188
189 wa->dma.length = CCP_DMAPOOL_MAX_SIZE;
190
191 memset(wa->address, 0, CCP_DMAPOOL_MAX_SIZE);
192 } else {
193 wa->address = kzalloc(len, GFP_KERNEL);
194 if (!wa->address)
195 return -ENOMEM;
196
197 wa->dma.address = dma_map_single(wa->dev, wa->address, len,
198 dir);
199 if (!wa->dma.address)
200 return -ENOMEM;
201
202 wa->dma.length = len;
203 }
204 wa->dma.dir = dir;
205
206 return 0;
207}
208
209static void ccp_set_dm_area(struct ccp_dm_workarea *wa, unsigned int wa_offset,
210 struct scatterlist *sg, unsigned int sg_offset,
211 unsigned int len)
212{
213 WARN_ON(!wa->address);
214
215 scatterwalk_map_and_copy(wa->address + wa_offset, sg, sg_offset, len,
216 0);
217}
218
219static void ccp_get_dm_area(struct ccp_dm_workarea *wa, unsigned int wa_offset,
220 struct scatterlist *sg, unsigned int sg_offset,
221 unsigned int len)
222{
223 WARN_ON(!wa->address);
224
225 scatterwalk_map_and_copy(wa->address + wa_offset, sg, sg_offset, len,
226 1);
227}
228
229static int ccp_reverse_set_dm_area(struct ccp_dm_workarea *wa,
230 struct scatterlist *sg,
231 unsigned int len, unsigned int se_len,
232 bool sign_extend)
233{
234 unsigned int nbytes, sg_offset, dm_offset, ksb_len, i;
235 u8 buffer[CCP_REVERSE_BUF_SIZE];
236
237 if (WARN_ON(se_len > sizeof(buffer)))
238 return -EINVAL;
239
240 sg_offset = len;
241 dm_offset = 0;
242 nbytes = len;
243 while (nbytes) {
244 ksb_len = min_t(unsigned int, nbytes, se_len);
245 sg_offset -= ksb_len;
246
247 scatterwalk_map_and_copy(buffer, sg, sg_offset, ksb_len, 0);
248 for (i = 0; i < ksb_len; i++)
249 wa->address[dm_offset + i] = buffer[ksb_len - i - 1];
250
251 dm_offset += ksb_len;
252 nbytes -= ksb_len;
253
254 if ((ksb_len != se_len) && sign_extend) {
255
256 if (wa->address[dm_offset - 1] & 0x80)
257 memset(wa->address + dm_offset, 0xff,
258 se_len - ksb_len);
259 }
260 }
261
262 return 0;
263}
264
265static void ccp_reverse_get_dm_area(struct ccp_dm_workarea *wa,
266 struct scatterlist *sg,
267 unsigned int len)
268{
269 unsigned int nbytes, sg_offset, dm_offset, ksb_len, i;
270 u8 buffer[CCP_REVERSE_BUF_SIZE];
271
272 sg_offset = 0;
273 dm_offset = len;
274 nbytes = len;
275 while (nbytes) {
276 ksb_len = min_t(unsigned int, nbytes, sizeof(buffer));
277 dm_offset -= ksb_len;
278
279 for (i = 0; i < ksb_len; i++)
280 buffer[ksb_len - i - 1] = wa->address[dm_offset + i];
281 scatterwalk_map_and_copy(buffer, sg, sg_offset, ksb_len, 1);
282
283 sg_offset += ksb_len;
284 nbytes -= ksb_len;
285 }
286}
287
288static void ccp_free_data(struct ccp_data *data, struct ccp_cmd_queue *cmd_q)
289{
290 ccp_dm_free(&data->dm_wa);
291 ccp_sg_free(&data->sg_wa);
292}
293
294static int ccp_init_data(struct ccp_data *data, struct ccp_cmd_queue *cmd_q,
295 struct scatterlist *sg, u64 sg_len,
296 unsigned int dm_len,
297 enum dma_data_direction dir)
298{
299 int ret;
300
301 memset(data, 0, sizeof(*data));
302
303 ret = ccp_init_sg_workarea(&data->sg_wa, cmd_q->ccp->dev, sg, sg_len,
304 dir);
305 if (ret)
306 goto e_err;
307
308 ret = ccp_init_dm_workarea(&data->dm_wa, cmd_q, dm_len, dir);
309 if (ret)
310 goto e_err;
311
312 return 0;
313
314e_err:
315 ccp_free_data(data, cmd_q);
316
317 return ret;
318}
319
320static unsigned int ccp_queue_buf(struct ccp_data *data, unsigned int from)
321{
322 struct ccp_sg_workarea *sg_wa = &data->sg_wa;
323 struct ccp_dm_workarea *dm_wa = &data->dm_wa;
324 unsigned int buf_count, nbytes;
325
326
327 if (!from)
328 memset(dm_wa->address, 0, dm_wa->length);
329
330 if (!sg_wa->sg)
331 return 0;
332
333
334
335
336
337 nbytes = min_t(u64, sg_wa->bytes_left, dm_wa->length);
338 scatterwalk_map_and_copy(dm_wa->address, sg_wa->sg, sg_wa->sg_used,
339 nbytes, from);
340
341
342 buf_count = 0;
343 while (sg_wa->bytes_left && (buf_count < dm_wa->length)) {
344 nbytes = min(sg_wa->sg->length - sg_wa->sg_used,
345 dm_wa->length - buf_count);
346 nbytes = min_t(u64, sg_wa->bytes_left, nbytes);
347
348 buf_count += nbytes;
349 ccp_update_sg_workarea(sg_wa, nbytes);
350 }
351
352 return buf_count;
353}
354
355static unsigned int ccp_fill_queue_buf(struct ccp_data *data)
356{
357 return ccp_queue_buf(data, 0);
358}
359
360static unsigned int ccp_empty_queue_buf(struct ccp_data *data)
361{
362 return ccp_queue_buf(data, 1);
363}
364
365static void ccp_prepare_data(struct ccp_data *src, struct ccp_data *dst,
366 struct ccp_op *op, unsigned int block_size,
367 bool blocksize_op)
368{
369 unsigned int sg_src_len, sg_dst_len, op_len;
370
371
372
373
374
375
376 sg_src_len = sg_dma_len(src->sg_wa.sg) - src->sg_wa.sg_used;
377 sg_src_len = min_t(u64, src->sg_wa.bytes_left, sg_src_len);
378
379 if (dst) {
380 sg_dst_len = sg_dma_len(dst->sg_wa.sg) - dst->sg_wa.sg_used;
381 sg_dst_len = min_t(u64, src->sg_wa.bytes_left, sg_dst_len);
382 op_len = min(sg_src_len, sg_dst_len);
383 } else {
384 op_len = sg_src_len;
385 }
386
387
388
389
390
391 op_len = max(op_len, block_size);
392
393
394 op->soc = 0;
395
396 if (sg_src_len < block_size) {
397
398
399
400 int cp_len = ccp_fill_queue_buf(src);
401
402 op->soc = 1;
403 op->src.u.dma.address = src->dm_wa.dma.address;
404 op->src.u.dma.offset = 0;
405 op->src.u.dma.length = (blocksize_op) ? block_size : cp_len;
406 } else {
407
408
409
410 op->src.u.dma.address = sg_dma_address(src->sg_wa.sg);
411 op->src.u.dma.offset = src->sg_wa.sg_used;
412 op->src.u.dma.length = op_len & ~(block_size - 1);
413
414 ccp_update_sg_workarea(&src->sg_wa, op->src.u.dma.length);
415 }
416
417 if (dst) {
418 if (sg_dst_len < block_size) {
419
420
421
422
423 op->soc = 1;
424 op->dst.u.dma.address = dst->dm_wa.dma.address;
425 op->dst.u.dma.offset = 0;
426 op->dst.u.dma.length = op->src.u.dma.length;
427 } else {
428
429
430
431 op->dst.u.dma.address = sg_dma_address(dst->sg_wa.sg);
432 op->dst.u.dma.offset = dst->sg_wa.sg_used;
433 op->dst.u.dma.length = op->src.u.dma.length;
434 }
435 }
436}
437
438static void ccp_process_data(struct ccp_data *src, struct ccp_data *dst,
439 struct ccp_op *op)
440{
441 op->init = 0;
442
443 if (dst) {
444 if (op->dst.u.dma.address == dst->dm_wa.dma.address)
445 ccp_empty_queue_buf(dst);
446 else
447 ccp_update_sg_workarea(&dst->sg_wa,
448 op->dst.u.dma.length);
449 }
450}
451
452static int ccp_copy_to_from_ksb(struct ccp_cmd_queue *cmd_q,
453 struct ccp_dm_workarea *wa, u32 jobid, u32 ksb,
454 u32 byte_swap, bool from)
455{
456 struct ccp_op op;
457
458 memset(&op, 0, sizeof(op));
459
460 op.cmd_q = cmd_q;
461 op.jobid = jobid;
462 op.eom = 1;
463
464 if (from) {
465 op.soc = 1;
466 op.src.type = CCP_MEMTYPE_KSB;
467 op.src.u.ksb = ksb;
468 op.dst.type = CCP_MEMTYPE_SYSTEM;
469 op.dst.u.dma.address = wa->dma.address;
470 op.dst.u.dma.length = wa->length;
471 } else {
472 op.src.type = CCP_MEMTYPE_SYSTEM;
473 op.src.u.dma.address = wa->dma.address;
474 op.src.u.dma.length = wa->length;
475 op.dst.type = CCP_MEMTYPE_KSB;
476 op.dst.u.ksb = ksb;
477 }
478
479 op.u.passthru.byte_swap = byte_swap;
480
481 return cmd_q->ccp->vdata->perform->perform_passthru(&op);
482}
483
484static int ccp_copy_to_ksb(struct ccp_cmd_queue *cmd_q,
485 struct ccp_dm_workarea *wa, u32 jobid, u32 ksb,
486 u32 byte_swap)
487{
488 return ccp_copy_to_from_ksb(cmd_q, wa, jobid, ksb, byte_swap, false);
489}
490
491static int ccp_copy_from_ksb(struct ccp_cmd_queue *cmd_q,
492 struct ccp_dm_workarea *wa, u32 jobid, u32 ksb,
493 u32 byte_swap)
494{
495 return ccp_copy_to_from_ksb(cmd_q, wa, jobid, ksb, byte_swap, true);
496}
497
498static int ccp_run_aes_cmac_cmd(struct ccp_cmd_queue *cmd_q,
499 struct ccp_cmd *cmd)
500{
501 struct ccp_aes_engine *aes = &cmd->u.aes;
502 struct ccp_dm_workarea key, ctx;
503 struct ccp_data src;
504 struct ccp_op op;
505 unsigned int dm_offset;
506 int ret;
507
508 if (!((aes->key_len == AES_KEYSIZE_128) ||
509 (aes->key_len == AES_KEYSIZE_192) ||
510 (aes->key_len == AES_KEYSIZE_256)))
511 return -EINVAL;
512
513 if (aes->src_len & (AES_BLOCK_SIZE - 1))
514 return -EINVAL;
515
516 if (aes->iv_len != AES_BLOCK_SIZE)
517 return -EINVAL;
518
519 if (!aes->key || !aes->iv || !aes->src)
520 return -EINVAL;
521
522 if (aes->cmac_final) {
523 if (aes->cmac_key_len != AES_BLOCK_SIZE)
524 return -EINVAL;
525
526 if (!aes->cmac_key)
527 return -EINVAL;
528 }
529
530 BUILD_BUG_ON(CCP_AES_KEY_KSB_COUNT != 1);
531 BUILD_BUG_ON(CCP_AES_CTX_KSB_COUNT != 1);
532
533 ret = -EIO;
534 memset(&op, 0, sizeof(op));
535 op.cmd_q = cmd_q;
536 op.jobid = ccp_gen_jobid(cmd_q->ccp);
537 op.ksb_key = cmd_q->ksb_key;
538 op.ksb_ctx = cmd_q->ksb_ctx;
539 op.init = 1;
540 op.u.aes.type = aes->type;
541 op.u.aes.mode = aes->mode;
542 op.u.aes.action = aes->action;
543
544
545
546
547
548
549 ret = ccp_init_dm_workarea(&key, cmd_q,
550 CCP_AES_KEY_KSB_COUNT * CCP_KSB_BYTES,
551 DMA_TO_DEVICE);
552 if (ret)
553 return ret;
554
555 dm_offset = CCP_KSB_BYTES - aes->key_len;
556 ccp_set_dm_area(&key, dm_offset, aes->key, 0, aes->key_len);
557 ret = ccp_copy_to_ksb(cmd_q, &key, op.jobid, op.ksb_key,
558 CCP_PASSTHRU_BYTESWAP_256BIT);
559 if (ret) {
560 cmd->engine_error = cmd_q->cmd_error;
561 goto e_key;
562 }
563
564
565
566
567
568 ret = ccp_init_dm_workarea(&ctx, cmd_q,
569 CCP_AES_CTX_KSB_COUNT * CCP_KSB_BYTES,
570 DMA_BIDIRECTIONAL);
571 if (ret)
572 goto e_key;
573
574 dm_offset = CCP_KSB_BYTES - AES_BLOCK_SIZE;
575 ccp_set_dm_area(&ctx, dm_offset, aes->iv, 0, aes->iv_len);
576 ret = ccp_copy_to_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
577 CCP_PASSTHRU_BYTESWAP_256BIT);
578 if (ret) {
579 cmd->engine_error = cmd_q->cmd_error;
580 goto e_ctx;
581 }
582
583
584 ret = ccp_init_data(&src, cmd_q, aes->src, aes->src_len,
585 AES_BLOCK_SIZE, DMA_TO_DEVICE);
586 if (ret)
587 goto e_ctx;
588
589 while (src.sg_wa.bytes_left) {
590 ccp_prepare_data(&src, NULL, &op, AES_BLOCK_SIZE, true);
591 if (aes->cmac_final && !src.sg_wa.bytes_left) {
592 op.eom = 1;
593
594
595 ret = ccp_copy_from_ksb(cmd_q, &ctx, op.jobid,
596 op.ksb_ctx,
597 CCP_PASSTHRU_BYTESWAP_256BIT);
598 if (ret) {
599 cmd->engine_error = cmd_q->cmd_error;
600 goto e_src;
601 }
602
603 ccp_set_dm_area(&ctx, 0, aes->cmac_key, 0,
604 aes->cmac_key_len);
605 ret = ccp_copy_to_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
606 CCP_PASSTHRU_BYTESWAP_256BIT);
607 if (ret) {
608 cmd->engine_error = cmd_q->cmd_error;
609 goto e_src;
610 }
611 }
612
613 ret = cmd_q->ccp->vdata->perform->perform_aes(&op);
614 if (ret) {
615 cmd->engine_error = cmd_q->cmd_error;
616 goto e_src;
617 }
618
619 ccp_process_data(&src, NULL, &op);
620 }
621
622
623
624
625 ret = ccp_copy_from_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
626 CCP_PASSTHRU_BYTESWAP_256BIT);
627 if (ret) {
628 cmd->engine_error = cmd_q->cmd_error;
629 goto e_src;
630 }
631
632
633 dm_offset = CCP_KSB_BYTES - AES_BLOCK_SIZE;
634 ccp_get_dm_area(&ctx, dm_offset, aes->iv, 0, aes->iv_len);
635
636e_src:
637 ccp_free_data(&src, cmd_q);
638
639e_ctx:
640 ccp_dm_free(&ctx);
641
642e_key:
643 ccp_dm_free(&key);
644
645 return ret;
646}
647
648static int ccp_run_aes_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
649{
650 struct ccp_aes_engine *aes = &cmd->u.aes;
651 struct ccp_dm_workarea key, ctx;
652 struct ccp_data src, dst;
653 struct ccp_op op;
654 unsigned int dm_offset;
655 bool in_place = false;
656 int ret;
657
658 if (aes->mode == CCP_AES_MODE_CMAC)
659 return ccp_run_aes_cmac_cmd(cmd_q, cmd);
660
661 if (!((aes->key_len == AES_KEYSIZE_128) ||
662 (aes->key_len == AES_KEYSIZE_192) ||
663 (aes->key_len == AES_KEYSIZE_256)))
664 return -EINVAL;
665
666 if (((aes->mode == CCP_AES_MODE_ECB) ||
667 (aes->mode == CCP_AES_MODE_CBC) ||
668 (aes->mode == CCP_AES_MODE_CFB)) &&
669 (aes->src_len & (AES_BLOCK_SIZE - 1)))
670 return -EINVAL;
671
672 if (!aes->key || !aes->src || !aes->dst)
673 return -EINVAL;
674
675 if (aes->mode != CCP_AES_MODE_ECB) {
676 if (aes->iv_len != AES_BLOCK_SIZE)
677 return -EINVAL;
678
679 if (!aes->iv)
680 return -EINVAL;
681 }
682
683 BUILD_BUG_ON(CCP_AES_KEY_KSB_COUNT != 1);
684 BUILD_BUG_ON(CCP_AES_CTX_KSB_COUNT != 1);
685
686 ret = -EIO;
687 memset(&op, 0, sizeof(op));
688 op.cmd_q = cmd_q;
689 op.jobid = ccp_gen_jobid(cmd_q->ccp);
690 op.ksb_key = cmd_q->ksb_key;
691 op.ksb_ctx = cmd_q->ksb_ctx;
692 op.init = (aes->mode == CCP_AES_MODE_ECB) ? 0 : 1;
693 op.u.aes.type = aes->type;
694 op.u.aes.mode = aes->mode;
695 op.u.aes.action = aes->action;
696
697
698
699
700
701
702 ret = ccp_init_dm_workarea(&key, cmd_q,
703 CCP_AES_KEY_KSB_COUNT * CCP_KSB_BYTES,
704 DMA_TO_DEVICE);
705 if (ret)
706 return ret;
707
708 dm_offset = CCP_KSB_BYTES - aes->key_len;
709 ccp_set_dm_area(&key, dm_offset, aes->key, 0, aes->key_len);
710 ret = ccp_copy_to_ksb(cmd_q, &key, op.jobid, op.ksb_key,
711 CCP_PASSTHRU_BYTESWAP_256BIT);
712 if (ret) {
713 cmd->engine_error = cmd_q->cmd_error;
714 goto e_key;
715 }
716
717
718
719
720
721 ret = ccp_init_dm_workarea(&ctx, cmd_q,
722 CCP_AES_CTX_KSB_COUNT * CCP_KSB_BYTES,
723 DMA_BIDIRECTIONAL);
724 if (ret)
725 goto e_key;
726
727 if (aes->mode != CCP_AES_MODE_ECB) {
728
729 dm_offset = CCP_KSB_BYTES - AES_BLOCK_SIZE;
730 ccp_set_dm_area(&ctx, dm_offset, aes->iv, 0, aes->iv_len);
731 ret = ccp_copy_to_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
732 CCP_PASSTHRU_BYTESWAP_256BIT);
733 if (ret) {
734 cmd->engine_error = cmd_q->cmd_error;
735 goto e_ctx;
736 }
737 }
738
739
740
741
742
743 if (sg_virt(aes->src) == sg_virt(aes->dst))
744 in_place = true;
745
746 ret = ccp_init_data(&src, cmd_q, aes->src, aes->src_len,
747 AES_BLOCK_SIZE,
748 in_place ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
749 if (ret)
750 goto e_ctx;
751
752 if (in_place) {
753 dst = src;
754 } else {
755 ret = ccp_init_data(&dst, cmd_q, aes->dst, aes->src_len,
756 AES_BLOCK_SIZE, DMA_FROM_DEVICE);
757 if (ret)
758 goto e_src;
759 }
760
761
762 while (src.sg_wa.bytes_left) {
763 ccp_prepare_data(&src, &dst, &op, AES_BLOCK_SIZE, true);
764 if (!src.sg_wa.bytes_left) {
765 op.eom = 1;
766
767
768
769
770
771 if (aes->mode == CCP_AES_MODE_ECB)
772 op.soc = 1;
773 }
774
775 ret = cmd_q->ccp->vdata->perform->perform_aes(&op);
776 if (ret) {
777 cmd->engine_error = cmd_q->cmd_error;
778 goto e_dst;
779 }
780
781 ccp_process_data(&src, &dst, &op);
782 }
783
784 if (aes->mode != CCP_AES_MODE_ECB) {
785
786
787
788 ret = ccp_copy_from_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
789 CCP_PASSTHRU_BYTESWAP_256BIT);
790 if (ret) {
791 cmd->engine_error = cmd_q->cmd_error;
792 goto e_dst;
793 }
794
795
796 dm_offset = CCP_KSB_BYTES - AES_BLOCK_SIZE;
797 ccp_get_dm_area(&ctx, dm_offset, aes->iv, 0, aes->iv_len);
798 }
799
800e_dst:
801 if (!in_place)
802 ccp_free_data(&dst, cmd_q);
803
804e_src:
805 ccp_free_data(&src, cmd_q);
806
807e_ctx:
808 ccp_dm_free(&ctx);
809
810e_key:
811 ccp_dm_free(&key);
812
813 return ret;
814}
815
816static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
817 struct ccp_cmd *cmd)
818{
819 struct ccp_xts_aes_engine *xts = &cmd->u.xts;
820 struct ccp_dm_workarea key, ctx;
821 struct ccp_data src, dst;
822 struct ccp_op op;
823 unsigned int unit_size, dm_offset;
824 bool in_place = false;
825 int ret;
826
827 switch (xts->unit_size) {
828 case CCP_XTS_AES_UNIT_SIZE_16:
829 unit_size = 16;
830 break;
831 case CCP_XTS_AES_UNIT_SIZE_512:
832 unit_size = 512;
833 break;
834 case CCP_XTS_AES_UNIT_SIZE_1024:
835 unit_size = 1024;
836 break;
837 case CCP_XTS_AES_UNIT_SIZE_2048:
838 unit_size = 2048;
839 break;
840 case CCP_XTS_AES_UNIT_SIZE_4096:
841 unit_size = 4096;
842 break;
843
844 default:
845 return -EINVAL;
846 }
847
848 if (xts->key_len != AES_KEYSIZE_128)
849 return -EINVAL;
850
851 if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1)))
852 return -EINVAL;
853
854 if (xts->iv_len != AES_BLOCK_SIZE)
855 return -EINVAL;
856
857 if (!xts->key || !xts->iv || !xts->src || !xts->dst)
858 return -EINVAL;
859
860 BUILD_BUG_ON(CCP_XTS_AES_KEY_KSB_COUNT != 1);
861 BUILD_BUG_ON(CCP_XTS_AES_CTX_KSB_COUNT != 1);
862
863 ret = -EIO;
864 memset(&op, 0, sizeof(op));
865 op.cmd_q = cmd_q;
866 op.jobid = ccp_gen_jobid(cmd_q->ccp);
867 op.ksb_key = cmd_q->ksb_key;
868 op.ksb_ctx = cmd_q->ksb_ctx;
869 op.init = 1;
870 op.u.xts.action = xts->action;
871 op.u.xts.unit_size = xts->unit_size;
872
873
874
875
876
877
878 ret = ccp_init_dm_workarea(&key, cmd_q,
879 CCP_XTS_AES_KEY_KSB_COUNT * CCP_KSB_BYTES,
880 DMA_TO_DEVICE);
881 if (ret)
882 return ret;
883
884 dm_offset = CCP_KSB_BYTES - AES_KEYSIZE_128;
885 ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len);
886 ccp_set_dm_area(&key, 0, xts->key, dm_offset, xts->key_len);
887 ret = ccp_copy_to_ksb(cmd_q, &key, op.jobid, op.ksb_key,
888 CCP_PASSTHRU_BYTESWAP_256BIT);
889 if (ret) {
890 cmd->engine_error = cmd_q->cmd_error;
891 goto e_key;
892 }
893
894
895
896
897
898 ret = ccp_init_dm_workarea(&ctx, cmd_q,
899 CCP_XTS_AES_CTX_KSB_COUNT * CCP_KSB_BYTES,
900 DMA_BIDIRECTIONAL);
901 if (ret)
902 goto e_key;
903
904 ccp_set_dm_area(&ctx, 0, xts->iv, 0, xts->iv_len);
905 ret = ccp_copy_to_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
906 CCP_PASSTHRU_BYTESWAP_NOOP);
907 if (ret) {
908 cmd->engine_error = cmd_q->cmd_error;
909 goto e_ctx;
910 }
911
912
913
914
915
916 if (sg_virt(xts->src) == sg_virt(xts->dst))
917 in_place = true;
918
919 ret = ccp_init_data(&src, cmd_q, xts->src, xts->src_len,
920 unit_size,
921 in_place ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
922 if (ret)
923 goto e_ctx;
924
925 if (in_place) {
926 dst = src;
927 } else {
928 ret = ccp_init_data(&dst, cmd_q, xts->dst, xts->src_len,
929 unit_size, DMA_FROM_DEVICE);
930 if (ret)
931 goto e_src;
932 }
933
934
935 while (src.sg_wa.bytes_left) {
936 ccp_prepare_data(&src, &dst, &op, unit_size, true);
937 if (!src.sg_wa.bytes_left)
938 op.eom = 1;
939
940 ret = cmd_q->ccp->vdata->perform->perform_xts_aes(&op);
941 if (ret) {
942 cmd->engine_error = cmd_q->cmd_error;
943 goto e_dst;
944 }
945
946 ccp_process_data(&src, &dst, &op);
947 }
948
949
950
951
952 ret = ccp_copy_from_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
953 CCP_PASSTHRU_BYTESWAP_256BIT);
954 if (ret) {
955 cmd->engine_error = cmd_q->cmd_error;
956 goto e_dst;
957 }
958
959
960 dm_offset = CCP_KSB_BYTES - AES_BLOCK_SIZE;
961 ccp_get_dm_area(&ctx, dm_offset, xts->iv, 0, xts->iv_len);
962
963e_dst:
964 if (!in_place)
965 ccp_free_data(&dst, cmd_q);
966
967e_src:
968 ccp_free_data(&src, cmd_q);
969
970e_ctx:
971 ccp_dm_free(&ctx);
972
973e_key:
974 ccp_dm_free(&key);
975
976 return ret;
977}
978
979static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
980{
981 struct ccp_sha_engine *sha = &cmd->u.sha;
982 struct ccp_dm_workarea ctx;
983 struct ccp_data src;
984 struct ccp_op op;
985 int ret;
986
987 if (sha->ctx_len != CCP_SHA_CTXSIZE)
988 return -EINVAL;
989
990 if (!sha->ctx)
991 return -EINVAL;
992
993 if (!sha->final && (sha->src_len & (CCP_SHA_BLOCKSIZE - 1)))
994 return -EINVAL;
995
996 if (!sha->src_len) {
997 const u8 *sha_zero;
998
999
1000 if (!sha->final)
1001 return 0;
1002
1003
1004
1005
1006 if (sha->msg_bits)
1007 return -EINVAL;
1008
1009
1010
1011
1012
1013
1014
1015 switch (sha->type) {
1016 case CCP_SHA_TYPE_1:
1017 sha_zero = sha1_zero_message_hash;
1018 break;
1019 case CCP_SHA_TYPE_224:
1020 sha_zero = sha224_zero_message_hash;
1021 break;
1022 case CCP_SHA_TYPE_256:
1023 sha_zero = sha256_zero_message_hash;
1024 break;
1025 default:
1026 return -EINVAL;
1027 }
1028
1029 scatterwalk_map_and_copy((void *)sha_zero, sha->ctx, 0,
1030 sha->ctx_len, 1);
1031
1032 return 0;
1033 }
1034
1035 if (!sha->src)
1036 return -EINVAL;
1037
1038 BUILD_BUG_ON(CCP_SHA_KSB_COUNT != 1);
1039
1040 memset(&op, 0, sizeof(op));
1041 op.cmd_q = cmd_q;
1042 op.jobid = ccp_gen_jobid(cmd_q->ccp);
1043 op.ksb_ctx = cmd_q->ksb_ctx;
1044 op.u.sha.type = sha->type;
1045 op.u.sha.msg_bits = sha->msg_bits;
1046
1047
1048
1049
1050
1051 ret = ccp_init_dm_workarea(&ctx, cmd_q,
1052 CCP_SHA_KSB_COUNT * CCP_KSB_BYTES,
1053 DMA_BIDIRECTIONAL);
1054 if (ret)
1055 return ret;
1056
1057 if (sha->first) {
1058 const __be32 *init;
1059
1060 switch (sha->type) {
1061 case CCP_SHA_TYPE_1:
1062 init = ccp_sha1_init;
1063 break;
1064 case CCP_SHA_TYPE_224:
1065 init = ccp_sha224_init;
1066 break;
1067 case CCP_SHA_TYPE_256:
1068 init = ccp_sha256_init;
1069 break;
1070 default:
1071 ret = -EINVAL;
1072 goto e_ctx;
1073 }
1074 memcpy(ctx.address, init, CCP_SHA_CTXSIZE);
1075 } else {
1076 ccp_set_dm_area(&ctx, 0, sha->ctx, 0, sha->ctx_len);
1077 }
1078
1079 ret = ccp_copy_to_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
1080 CCP_PASSTHRU_BYTESWAP_256BIT);
1081 if (ret) {
1082 cmd->engine_error = cmd_q->cmd_error;
1083 goto e_ctx;
1084 }
1085
1086
1087 ret = ccp_init_data(&src, cmd_q, sha->src, sha->src_len,
1088 CCP_SHA_BLOCKSIZE, DMA_TO_DEVICE);
1089 if (ret)
1090 goto e_ctx;
1091
1092 while (src.sg_wa.bytes_left) {
1093 ccp_prepare_data(&src, NULL, &op, CCP_SHA_BLOCKSIZE, false);
1094 if (sha->final && !src.sg_wa.bytes_left)
1095 op.eom = 1;
1096
1097 ret = cmd_q->ccp->vdata->perform->perform_sha(&op);
1098 if (ret) {
1099 cmd->engine_error = cmd_q->cmd_error;
1100 goto e_data;
1101 }
1102
1103 ccp_process_data(&src, NULL, &op);
1104 }
1105
1106
1107
1108
1109 ret = ccp_copy_from_ksb(cmd_q, &ctx, op.jobid, op.ksb_ctx,
1110 CCP_PASSTHRU_BYTESWAP_256BIT);
1111 if (ret) {
1112 cmd->engine_error = cmd_q->cmd_error;
1113 goto e_data;
1114 }
1115
1116 ccp_get_dm_area(&ctx, 0, sha->ctx, 0, sha->ctx_len);
1117
1118 if (sha->final && sha->opad) {
1119
1120 struct ccp_cmd hmac_cmd;
1121 struct scatterlist sg;
1122 u64 block_size, digest_size;
1123 u8 *hmac_buf;
1124
1125 switch (sha->type) {
1126 case CCP_SHA_TYPE_1:
1127 block_size = SHA1_BLOCK_SIZE;
1128 digest_size = SHA1_DIGEST_SIZE;
1129 break;
1130 case CCP_SHA_TYPE_224:
1131 block_size = SHA224_BLOCK_SIZE;
1132 digest_size = SHA224_DIGEST_SIZE;
1133 break;
1134 case CCP_SHA_TYPE_256:
1135 block_size = SHA256_BLOCK_SIZE;
1136 digest_size = SHA256_DIGEST_SIZE;
1137 break;
1138 default:
1139 ret = -EINVAL;
1140 goto e_data;
1141 }
1142
1143 if (sha->opad_len != block_size) {
1144 ret = -EINVAL;
1145 goto e_data;
1146 }
1147
1148 hmac_buf = kmalloc(block_size + digest_size, GFP_KERNEL);
1149 if (!hmac_buf) {
1150 ret = -ENOMEM;
1151 goto e_data;
1152 }
1153 sg_init_one(&sg, hmac_buf, block_size + digest_size);
1154
1155 scatterwalk_map_and_copy(hmac_buf, sha->opad, 0, block_size, 0);
1156 memcpy(hmac_buf + block_size, ctx.address, digest_size);
1157
1158 memset(&hmac_cmd, 0, sizeof(hmac_cmd));
1159 hmac_cmd.engine = CCP_ENGINE_SHA;
1160 hmac_cmd.u.sha.type = sha->type;
1161 hmac_cmd.u.sha.ctx = sha->ctx;
1162 hmac_cmd.u.sha.ctx_len = sha->ctx_len;
1163 hmac_cmd.u.sha.src = &sg;
1164 hmac_cmd.u.sha.src_len = block_size + digest_size;
1165 hmac_cmd.u.sha.opad = NULL;
1166 hmac_cmd.u.sha.opad_len = 0;
1167 hmac_cmd.u.sha.first = 1;
1168 hmac_cmd.u.sha.final = 1;
1169 hmac_cmd.u.sha.msg_bits = (block_size + digest_size) << 3;
1170
1171 ret = ccp_run_sha_cmd(cmd_q, &hmac_cmd);
1172 if (ret)
1173 cmd->engine_error = hmac_cmd.engine_error;
1174
1175 kfree(hmac_buf);
1176 }
1177
1178e_data:
1179 ccp_free_data(&src, cmd_q);
1180
1181e_ctx:
1182 ccp_dm_free(&ctx);
1183
1184 return ret;
1185}
1186
1187static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
1188{
1189 struct ccp_rsa_engine *rsa = &cmd->u.rsa;
1190 struct ccp_dm_workarea exp, src;
1191 struct ccp_data dst;
1192 struct ccp_op op;
1193 unsigned int ksb_count, i_len, o_len;
1194 int ret;
1195
1196 if (rsa->key_size > CCP_RSA_MAX_WIDTH)
1197 return -EINVAL;
1198
1199 if (!rsa->exp || !rsa->mod || !rsa->src || !rsa->dst)
1200 return -EINVAL;
1201
1202
1203
1204
1205
1206
1207
1208 o_len = ((rsa->key_size + 255) / 256) * 32;
1209 i_len = o_len * 2;
1210
1211 ksb_count = o_len / CCP_KSB_BYTES;
1212
1213 memset(&op, 0, sizeof(op));
1214 op.cmd_q = cmd_q;
1215 op.jobid = ccp_gen_jobid(cmd_q->ccp);
1216 op.ksb_key = ccp_alloc_ksb(cmd_q->ccp, ksb_count);
1217 if (!op.ksb_key)
1218 return -EIO;
1219
1220
1221
1222
1223
1224
1225
1226 ret = ccp_init_dm_workarea(&exp, cmd_q, o_len, DMA_TO_DEVICE);
1227 if (ret)
1228 goto e_ksb;
1229
1230 ret = ccp_reverse_set_dm_area(&exp, rsa->exp, rsa->exp_len,
1231 CCP_KSB_BYTES, false);
1232 if (ret)
1233 goto e_exp;
1234 ret = ccp_copy_to_ksb(cmd_q, &exp, op.jobid, op.ksb_key,
1235 CCP_PASSTHRU_BYTESWAP_NOOP);
1236 if (ret) {
1237 cmd->engine_error = cmd_q->cmd_error;
1238 goto e_exp;
1239 }
1240
1241
1242
1243
1244
1245 ret = ccp_init_dm_workarea(&src, cmd_q, i_len, DMA_TO_DEVICE);
1246 if (ret)
1247 goto e_exp;
1248
1249 ret = ccp_reverse_set_dm_area(&src, rsa->mod, rsa->mod_len,
1250 CCP_KSB_BYTES, false);
1251 if (ret)
1252 goto e_src;
1253 src.address += o_len;
1254 ret = ccp_reverse_set_dm_area(&src, rsa->src, rsa->src_len,
1255 CCP_KSB_BYTES, false);
1256 if (ret)
1257 goto e_src;
1258 src.address -= o_len;
1259
1260
1261 ret = ccp_init_data(&dst, cmd_q, rsa->dst, rsa->mod_len,
1262 o_len, DMA_FROM_DEVICE);
1263 if (ret)
1264 goto e_src;
1265
1266 op.soc = 1;
1267 op.src.u.dma.address = src.dma.address;
1268 op.src.u.dma.offset = 0;
1269 op.src.u.dma.length = i_len;
1270 op.dst.u.dma.address = dst.dm_wa.dma.address;
1271 op.dst.u.dma.offset = 0;
1272 op.dst.u.dma.length = o_len;
1273
1274 op.u.rsa.mod_size = rsa->key_size;
1275 op.u.rsa.input_len = i_len;
1276
1277 ret = cmd_q->ccp->vdata->perform->perform_rsa(&op);
1278 if (ret) {
1279 cmd->engine_error = cmd_q->cmd_error;
1280 goto e_dst;
1281 }
1282
1283 ccp_reverse_get_dm_area(&dst.dm_wa, rsa->dst, rsa->mod_len);
1284
1285e_dst:
1286 ccp_free_data(&dst, cmd_q);
1287
1288e_src:
1289 ccp_dm_free(&src);
1290
1291e_exp:
1292 ccp_dm_free(&exp);
1293
1294e_ksb:
1295 ccp_free_ksb(cmd_q->ccp, op.ksb_key, ksb_count);
1296
1297 return ret;
1298}
1299
1300static int ccp_run_passthru_cmd(struct ccp_cmd_queue *cmd_q,
1301 struct ccp_cmd *cmd)
1302{
1303 struct ccp_passthru_engine *pt = &cmd->u.passthru;
1304 struct ccp_dm_workarea mask;
1305 struct ccp_data src, dst;
1306 struct ccp_op op;
1307 bool in_place = false;
1308 unsigned int i;
1309 int ret;
1310
1311 if (!pt->final && (pt->src_len & (CCP_PASSTHRU_BLOCKSIZE - 1)))
1312 return -EINVAL;
1313
1314 if (!pt->src || !pt->dst)
1315 return -EINVAL;
1316
1317 if (pt->bit_mod != CCP_PASSTHRU_BITWISE_NOOP) {
1318 if (pt->mask_len != CCP_PASSTHRU_MASKSIZE)
1319 return -EINVAL;
1320 if (!pt->mask)
1321 return -EINVAL;
1322 }
1323
1324 BUILD_BUG_ON(CCP_PASSTHRU_KSB_COUNT != 1);
1325
1326 memset(&op, 0, sizeof(op));
1327 op.cmd_q = cmd_q;
1328 op.jobid = ccp_gen_jobid(cmd_q->ccp);
1329
1330 if (pt->bit_mod != CCP_PASSTHRU_BITWISE_NOOP) {
1331
1332 op.ksb_key = cmd_q->ksb_key;
1333
1334 ret = ccp_init_dm_workarea(&mask, cmd_q,
1335 CCP_PASSTHRU_KSB_COUNT *
1336 CCP_KSB_BYTES,
1337 DMA_TO_DEVICE);
1338 if (ret)
1339 return ret;
1340
1341 ccp_set_dm_area(&mask, 0, pt->mask, 0, pt->mask_len);
1342 ret = ccp_copy_to_ksb(cmd_q, &mask, op.jobid, op.ksb_key,
1343 CCP_PASSTHRU_BYTESWAP_NOOP);
1344 if (ret) {
1345 cmd->engine_error = cmd_q->cmd_error;
1346 goto e_mask;
1347 }
1348 }
1349
1350
1351
1352
1353
1354 if (sg_virt(pt->src) == sg_virt(pt->dst))
1355 in_place = true;
1356
1357 ret = ccp_init_data(&src, cmd_q, pt->src, pt->src_len,
1358 CCP_PASSTHRU_MASKSIZE,
1359 in_place ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1360 if (ret)
1361 goto e_mask;
1362
1363 if (in_place) {
1364 dst = src;
1365 } else {
1366 ret = ccp_init_data(&dst, cmd_q, pt->dst, pt->src_len,
1367 CCP_PASSTHRU_MASKSIZE, DMA_FROM_DEVICE);
1368 if (ret)
1369 goto e_src;
1370 }
1371
1372
1373
1374
1375
1376
1377
1378
1379 dst.sg_wa.sg_used = 0;
1380 for (i = 1; i <= src.sg_wa.dma_count; i++) {
1381 if (!dst.sg_wa.sg ||
1382 (dst.sg_wa.sg->length < src.sg_wa.sg->length)) {
1383 ret = -EINVAL;
1384 goto e_dst;
1385 }
1386
1387 if (i == src.sg_wa.dma_count) {
1388 op.eom = 1;
1389 op.soc = 1;
1390 }
1391
1392 op.src.type = CCP_MEMTYPE_SYSTEM;
1393 op.src.u.dma.address = sg_dma_address(src.sg_wa.sg);
1394 op.src.u.dma.offset = 0;
1395 op.src.u.dma.length = sg_dma_len(src.sg_wa.sg);
1396
1397 op.dst.type = CCP_MEMTYPE_SYSTEM;
1398 op.dst.u.dma.address = sg_dma_address(dst.sg_wa.sg);
1399 op.dst.u.dma.offset = dst.sg_wa.sg_used;
1400 op.dst.u.dma.length = op.src.u.dma.length;
1401
1402 ret = cmd_q->ccp->vdata->perform->perform_passthru(&op);
1403 if (ret) {
1404 cmd->engine_error = cmd_q->cmd_error;
1405 goto e_dst;
1406 }
1407
1408 dst.sg_wa.sg_used += src.sg_wa.sg->length;
1409 if (dst.sg_wa.sg_used == dst.sg_wa.sg->length) {
1410 dst.sg_wa.sg = sg_next(dst.sg_wa.sg);
1411 dst.sg_wa.sg_used = 0;
1412 }
1413 src.sg_wa.sg = sg_next(src.sg_wa.sg);
1414 }
1415
1416e_dst:
1417 if (!in_place)
1418 ccp_free_data(&dst, cmd_q);
1419
1420e_src:
1421 ccp_free_data(&src, cmd_q);
1422
1423e_mask:
1424 if (pt->bit_mod != CCP_PASSTHRU_BITWISE_NOOP)
1425 ccp_dm_free(&mask);
1426
1427 return ret;
1428}
1429
1430static int ccp_run_passthru_nomap_cmd(struct ccp_cmd_queue *cmd_q,
1431 struct ccp_cmd *cmd)
1432{
1433 struct ccp_passthru_nomap_engine *pt = &cmd->u.passthru_nomap;
1434 struct ccp_dm_workarea mask;
1435 struct ccp_op op;
1436 int ret;
1437
1438 if (!pt->final && (pt->src_len & (CCP_PASSTHRU_BLOCKSIZE - 1)))
1439 return -EINVAL;
1440
1441 if (!pt->src_dma || !pt->dst_dma)
1442 return -EINVAL;
1443
1444 if (pt->bit_mod != CCP_PASSTHRU_BITWISE_NOOP) {
1445 if (pt->mask_len != CCP_PASSTHRU_MASKSIZE)
1446 return -EINVAL;
1447 if (!pt->mask)
1448 return -EINVAL;
1449 }
1450
1451 BUILD_BUG_ON(CCP_PASSTHRU_KSB_COUNT != 1);
1452
1453 memset(&op, 0, sizeof(op));
1454 op.cmd_q = cmd_q;
1455 op.jobid = ccp_gen_jobid(cmd_q->ccp);
1456
1457 if (pt->bit_mod != CCP_PASSTHRU_BITWISE_NOOP) {
1458
1459 op.ksb_key = cmd_q->ksb_key;
1460
1461 mask.length = pt->mask_len;
1462 mask.dma.address = pt->mask;
1463 mask.dma.length = pt->mask_len;
1464
1465 ret = ccp_copy_to_ksb(cmd_q, &mask, op.jobid, op.ksb_key,
1466 CCP_PASSTHRU_BYTESWAP_NOOP);
1467 if (ret) {
1468 cmd->engine_error = cmd_q->cmd_error;
1469 return ret;
1470 }
1471 }
1472
1473
1474 op.eom = 1;
1475 op.soc = 1;
1476
1477 op.src.type = CCP_MEMTYPE_SYSTEM;
1478 op.src.u.dma.address = pt->src_dma;
1479 op.src.u.dma.offset = 0;
1480 op.src.u.dma.length = pt->src_len;
1481
1482 op.dst.type = CCP_MEMTYPE_SYSTEM;
1483 op.dst.u.dma.address = pt->dst_dma;
1484 op.dst.u.dma.offset = 0;
1485 op.dst.u.dma.length = pt->src_len;
1486
1487 ret = cmd_q->ccp->vdata->perform->perform_passthru(&op);
1488 if (ret)
1489 cmd->engine_error = cmd_q->cmd_error;
1490
1491 return ret;
1492}
1493
1494static int ccp_run_ecc_mm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
1495{
1496 struct ccp_ecc_engine *ecc = &cmd->u.ecc;
1497 struct ccp_dm_workarea src, dst;
1498 struct ccp_op op;
1499 int ret;
1500 u8 *save;
1501
1502 if (!ecc->u.mm.operand_1 ||
1503 (ecc->u.mm.operand_1_len > CCP_ECC_MODULUS_BYTES))
1504 return -EINVAL;
1505
1506 if (ecc->function != CCP_ECC_FUNCTION_MINV_384BIT)
1507 if (!ecc->u.mm.operand_2 ||
1508 (ecc->u.mm.operand_2_len > CCP_ECC_MODULUS_BYTES))
1509 return -EINVAL;
1510
1511 if (!ecc->u.mm.result ||
1512 (ecc->u.mm.result_len < CCP_ECC_MODULUS_BYTES))
1513 return -EINVAL;
1514
1515 memset(&op, 0, sizeof(op));
1516 op.cmd_q = cmd_q;
1517 op.jobid = ccp_gen_jobid(cmd_q->ccp);
1518
1519
1520
1521
1522
1523
1524 ret = ccp_init_dm_workarea(&src, cmd_q, CCP_ECC_SRC_BUF_SIZE,
1525 DMA_TO_DEVICE);
1526 if (ret)
1527 return ret;
1528
1529
1530
1531
1532 save = src.address;
1533
1534
1535 ret = ccp_reverse_set_dm_area(&src, ecc->mod, ecc->mod_len,
1536 CCP_ECC_OPERAND_SIZE, false);
1537 if (ret)
1538 goto e_src;
1539 src.address += CCP_ECC_OPERAND_SIZE;
1540
1541
1542 ret = ccp_reverse_set_dm_area(&src, ecc->u.mm.operand_1,
1543 ecc->u.mm.operand_1_len,
1544 CCP_ECC_OPERAND_SIZE, false);
1545 if (ret)
1546 goto e_src;
1547 src.address += CCP_ECC_OPERAND_SIZE;
1548
1549 if (ecc->function != CCP_ECC_FUNCTION_MINV_384BIT) {
1550
1551 ret = ccp_reverse_set_dm_area(&src, ecc->u.mm.operand_2,
1552 ecc->u.mm.operand_2_len,
1553 CCP_ECC_OPERAND_SIZE, false);
1554 if (ret)
1555 goto e_src;
1556 src.address += CCP_ECC_OPERAND_SIZE;
1557 }
1558
1559
1560 src.address = save;
1561
1562
1563 ret = ccp_init_dm_workarea(&dst, cmd_q, CCP_ECC_DST_BUF_SIZE,
1564 DMA_FROM_DEVICE);
1565 if (ret)
1566 goto e_src;
1567
1568 op.soc = 1;
1569 op.src.u.dma.address = src.dma.address;
1570 op.src.u.dma.offset = 0;
1571 op.src.u.dma.length = src.length;
1572 op.dst.u.dma.address = dst.dma.address;
1573 op.dst.u.dma.offset = 0;
1574 op.dst.u.dma.length = dst.length;
1575
1576 op.u.ecc.function = cmd->u.ecc.function;
1577
1578 ret = cmd_q->ccp->vdata->perform->perform_ecc(&op);
1579 if (ret) {
1580 cmd->engine_error = cmd_q->cmd_error;
1581 goto e_dst;
1582 }
1583
1584 ecc->ecc_result = le16_to_cpup(
1585 (const __le16 *)(dst.address + CCP_ECC_RESULT_OFFSET));
1586 if (!(ecc->ecc_result & CCP_ECC_RESULT_SUCCESS)) {
1587 ret = -EIO;
1588 goto e_dst;
1589 }
1590
1591
1592 ccp_reverse_get_dm_area(&dst, ecc->u.mm.result, CCP_ECC_MODULUS_BYTES);
1593
1594e_dst:
1595 ccp_dm_free(&dst);
1596
1597e_src:
1598 ccp_dm_free(&src);
1599
1600 return ret;
1601}
1602
1603static int ccp_run_ecc_pm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
1604{
1605 struct ccp_ecc_engine *ecc = &cmd->u.ecc;
1606 struct ccp_dm_workarea src, dst;
1607 struct ccp_op op;
1608 int ret;
1609 u8 *save;
1610
1611 if (!ecc->u.pm.point_1.x ||
1612 (ecc->u.pm.point_1.x_len > CCP_ECC_MODULUS_BYTES) ||
1613 !ecc->u.pm.point_1.y ||
1614 (ecc->u.pm.point_1.y_len > CCP_ECC_MODULUS_BYTES))
1615 return -EINVAL;
1616
1617 if (ecc->function == CCP_ECC_FUNCTION_PADD_384BIT) {
1618 if (!ecc->u.pm.point_2.x ||
1619 (ecc->u.pm.point_2.x_len > CCP_ECC_MODULUS_BYTES) ||
1620 !ecc->u.pm.point_2.y ||
1621 (ecc->u.pm.point_2.y_len > CCP_ECC_MODULUS_BYTES))
1622 return -EINVAL;
1623 } else {
1624 if (!ecc->u.pm.domain_a ||
1625 (ecc->u.pm.domain_a_len > CCP_ECC_MODULUS_BYTES))
1626 return -EINVAL;
1627
1628 if (ecc->function == CCP_ECC_FUNCTION_PMUL_384BIT)
1629 if (!ecc->u.pm.scalar ||
1630 (ecc->u.pm.scalar_len > CCP_ECC_MODULUS_BYTES))
1631 return -EINVAL;
1632 }
1633
1634 if (!ecc->u.pm.result.x ||
1635 (ecc->u.pm.result.x_len < CCP_ECC_MODULUS_BYTES) ||
1636 !ecc->u.pm.result.y ||
1637 (ecc->u.pm.result.y_len < CCP_ECC_MODULUS_BYTES))
1638 return -EINVAL;
1639
1640 memset(&op, 0, sizeof(op));
1641 op.cmd_q = cmd_q;
1642 op.jobid = ccp_gen_jobid(cmd_q->ccp);
1643
1644
1645
1646
1647
1648
1649 ret = ccp_init_dm_workarea(&src, cmd_q, CCP_ECC_SRC_BUF_SIZE,
1650 DMA_TO_DEVICE);
1651 if (ret)
1652 return ret;
1653
1654
1655
1656
1657 save = src.address;
1658
1659
1660 ret = ccp_reverse_set_dm_area(&src, ecc->mod, ecc->mod_len,
1661 CCP_ECC_OPERAND_SIZE, false);
1662 if (ret)
1663 goto e_src;
1664 src.address += CCP_ECC_OPERAND_SIZE;
1665
1666
1667 ret = ccp_reverse_set_dm_area(&src, ecc->u.pm.point_1.x,
1668 ecc->u.pm.point_1.x_len,
1669 CCP_ECC_OPERAND_SIZE, false);
1670 if (ret)
1671 goto e_src;
1672 src.address += CCP_ECC_OPERAND_SIZE;
1673 ret = ccp_reverse_set_dm_area(&src, ecc->u.pm.point_1.y,
1674 ecc->u.pm.point_1.y_len,
1675 CCP_ECC_OPERAND_SIZE, false);
1676 if (ret)
1677 goto e_src;
1678 src.address += CCP_ECC_OPERAND_SIZE;
1679
1680
1681 *src.address = 0x01;
1682 src.address += CCP_ECC_OPERAND_SIZE;
1683
1684 if (ecc->function == CCP_ECC_FUNCTION_PADD_384BIT) {
1685
1686 ret = ccp_reverse_set_dm_area(&src, ecc->u.pm.point_2.x,
1687 ecc->u.pm.point_2.x_len,
1688 CCP_ECC_OPERAND_SIZE, false);
1689 if (ret)
1690 goto e_src;
1691 src.address += CCP_ECC_OPERAND_SIZE;
1692 ret = ccp_reverse_set_dm_area(&src, ecc->u.pm.point_2.y,
1693 ecc->u.pm.point_2.y_len,
1694 CCP_ECC_OPERAND_SIZE, false);
1695 if (ret)
1696 goto e_src;
1697 src.address += CCP_ECC_OPERAND_SIZE;
1698
1699
1700 *src.address = 0x01;
1701 src.address += CCP_ECC_OPERAND_SIZE;
1702 } else {
1703
1704 ret = ccp_reverse_set_dm_area(&src, ecc->u.pm.domain_a,
1705 ecc->u.pm.domain_a_len,
1706 CCP_ECC_OPERAND_SIZE, false);
1707 if (ret)
1708 goto e_src;
1709 src.address += CCP_ECC_OPERAND_SIZE;
1710
1711 if (ecc->function == CCP_ECC_FUNCTION_PMUL_384BIT) {
1712
1713 ret = ccp_reverse_set_dm_area(&src, ecc->u.pm.scalar,
1714 ecc->u.pm.scalar_len,
1715 CCP_ECC_OPERAND_SIZE,
1716 false);
1717 if (ret)
1718 goto e_src;
1719 src.address += CCP_ECC_OPERAND_SIZE;
1720 }
1721 }
1722
1723
1724 src.address = save;
1725
1726
1727 ret = ccp_init_dm_workarea(&dst, cmd_q, CCP_ECC_DST_BUF_SIZE,
1728 DMA_FROM_DEVICE);
1729 if (ret)
1730 goto e_src;
1731
1732 op.soc = 1;
1733 op.src.u.dma.address = src.dma.address;
1734 op.src.u.dma.offset = 0;
1735 op.src.u.dma.length = src.length;
1736 op.dst.u.dma.address = dst.dma.address;
1737 op.dst.u.dma.offset = 0;
1738 op.dst.u.dma.length = dst.length;
1739
1740 op.u.ecc.function = cmd->u.ecc.function;
1741
1742 ret = cmd_q->ccp->vdata->perform->perform_ecc(&op);
1743 if (ret) {
1744 cmd->engine_error = cmd_q->cmd_error;
1745 goto e_dst;
1746 }
1747
1748 ecc->ecc_result = le16_to_cpup(
1749 (const __le16 *)(dst.address + CCP_ECC_RESULT_OFFSET));
1750 if (!(ecc->ecc_result & CCP_ECC_RESULT_SUCCESS)) {
1751 ret = -EIO;
1752 goto e_dst;
1753 }
1754
1755
1756
1757
1758 save = dst.address;
1759
1760
1761 ccp_reverse_get_dm_area(&dst, ecc->u.pm.result.x,
1762 CCP_ECC_MODULUS_BYTES);
1763 dst.address += CCP_ECC_OUTPUT_SIZE;
1764 ccp_reverse_get_dm_area(&dst, ecc->u.pm.result.y,
1765 CCP_ECC_MODULUS_BYTES);
1766 dst.address += CCP_ECC_OUTPUT_SIZE;
1767
1768
1769 dst.address = save;
1770
1771e_dst:
1772 ccp_dm_free(&dst);
1773
1774e_src:
1775 ccp_dm_free(&src);
1776
1777 return ret;
1778}
1779
1780static int ccp_run_ecc_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
1781{
1782 struct ccp_ecc_engine *ecc = &cmd->u.ecc;
1783
1784 ecc->ecc_result = 0;
1785
1786 if (!ecc->mod ||
1787 (ecc->mod_len > CCP_ECC_MODULUS_BYTES))
1788 return -EINVAL;
1789
1790 switch (ecc->function) {
1791 case CCP_ECC_FUNCTION_MMUL_384BIT:
1792 case CCP_ECC_FUNCTION_MADD_384BIT:
1793 case CCP_ECC_FUNCTION_MINV_384BIT:
1794 return ccp_run_ecc_mm_cmd(cmd_q, cmd);
1795
1796 case CCP_ECC_FUNCTION_PADD_384BIT:
1797 case CCP_ECC_FUNCTION_PMUL_384BIT:
1798 case CCP_ECC_FUNCTION_PDBL_384BIT:
1799 return ccp_run_ecc_pm_cmd(cmd_q, cmd);
1800
1801 default:
1802 return -EINVAL;
1803 }
1804}
1805
1806int ccp_run_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
1807{
1808 int ret;
1809
1810 cmd->engine_error = 0;
1811 cmd_q->cmd_error = 0;
1812 cmd_q->int_rcvd = 0;
1813 cmd_q->free_slots = CMD_Q_DEPTH(ioread32(cmd_q->reg_status));
1814
1815 switch (cmd->engine) {
1816 case CCP_ENGINE_AES:
1817 ret = ccp_run_aes_cmd(cmd_q, cmd);
1818 break;
1819 case CCP_ENGINE_XTS_AES_128:
1820 ret = ccp_run_xts_aes_cmd(cmd_q, cmd);
1821 break;
1822 case CCP_ENGINE_SHA:
1823 ret = ccp_run_sha_cmd(cmd_q, cmd);
1824 break;
1825 case CCP_ENGINE_RSA:
1826 ret = ccp_run_rsa_cmd(cmd_q, cmd);
1827 break;
1828 case CCP_ENGINE_PASSTHRU:
1829 if (cmd->flags & CCP_CMD_PASSTHRU_NO_DMA_MAP)
1830 ret = ccp_run_passthru_nomap_cmd(cmd_q, cmd);
1831 else
1832 ret = ccp_run_passthru_cmd(cmd_q, cmd);
1833 break;
1834 case CCP_ENGINE_ECC:
1835 ret = ccp_run_ecc_cmd(cmd_q, cmd);
1836 break;
1837 default:
1838 ret = -EINVAL;
1839 }
1840
1841 return ret;
1842}
1843