2 * Cipher algorithms supported by the CESA: DES, 3DES and AES.
4 * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
5 * Author: Arnaud Ebalard <arno@natisbad.org>
7 * This work is based on an initial version written by
8 * Sebastian Andrzej Siewior < sebastian at breakpoint dot cc >
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
15 #include <crypto/aes.h>
16 #include <crypto/des.h>
20 struct mv_cesa_des_ctx
{
21 struct mv_cesa_ctx base
;
25 struct mv_cesa_des3_ctx
{
26 struct mv_cesa_ctx base
;
27 u8 key
[DES3_EDE_KEY_SIZE
];
30 struct mv_cesa_aes_ctx
{
31 struct mv_cesa_ctx base
;
32 struct crypto_aes_ctx aes
;
35 struct mv_cesa_ablkcipher_dma_iter
{
36 struct mv_cesa_dma_iter base
;
37 struct mv_cesa_sg_dma_iter src
;
38 struct mv_cesa_sg_dma_iter dst
;
42 mv_cesa_ablkcipher_req_iter_init(struct mv_cesa_ablkcipher_dma_iter
*iter
,
43 struct ablkcipher_request
*req
)
45 mv_cesa_req_dma_iter_init(&iter
->base
, req
->nbytes
);
46 mv_cesa_sg_dma_iter_init(&iter
->src
, req
->src
, DMA_TO_DEVICE
);
47 mv_cesa_sg_dma_iter_init(&iter
->dst
, req
->dst
, DMA_FROM_DEVICE
);
51 mv_cesa_ablkcipher_req_iter_next_op(struct mv_cesa_ablkcipher_dma_iter
*iter
)
53 iter
->src
.op_offset
= 0;
54 iter
->dst
.op_offset
= 0;
56 return mv_cesa_req_dma_iter_next_op(&iter
->base
);
60 mv_cesa_ablkcipher_dma_cleanup(struct ablkcipher_request
*req
)
62 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
64 if (req
->dst
!= req
->src
) {
65 dma_unmap_sg(cesa_dev
->dev
, req
->dst
, creq
->dst_nents
,
67 dma_unmap_sg(cesa_dev
->dev
, req
->src
, creq
->src_nents
,
70 dma_unmap_sg(cesa_dev
->dev
, req
->src
, creq
->src_nents
,
73 mv_cesa_dma_cleanup(&creq
->req
.dma
);
76 static inline void mv_cesa_ablkcipher_cleanup(struct ablkcipher_request
*req
)
78 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
80 if (creq
->req
.base
.type
== CESA_DMA_REQ
)
81 mv_cesa_ablkcipher_dma_cleanup(req
);
84 static void mv_cesa_ablkcipher_std_step(struct ablkcipher_request
*req
)
86 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
87 struct mv_cesa_ablkcipher_std_req
*sreq
= &creq
->req
.std
;
88 struct mv_cesa_engine
*engine
= sreq
->base
.engine
;
89 size_t len
= min_t(size_t, req
->nbytes
- sreq
->offset
,
90 CESA_SA_SRAM_PAYLOAD_SIZE
);
92 len
= sg_pcopy_to_buffer(req
->src
, creq
->src_nents
,
93 engine
->sram
+ CESA_SA_DATA_SRAM_OFFSET
,
97 mv_cesa_set_crypt_op_len(&sreq
->op
, len
);
99 /* FIXME: only update enc_len field */
100 if (!sreq
->skip_ctx
) {
101 memcpy(engine
->sram
, &sreq
->op
, sizeof(sreq
->op
));
102 sreq
->skip_ctx
= true;
104 memcpy(engine
->sram
, &sreq
->op
, sizeof(sreq
->op
.desc
));
107 mv_cesa_set_int_mask(engine
, CESA_SA_INT_ACCEL0_DONE
);
108 writel(CESA_SA_CFG_PARA_DIS
, engine
->regs
+ CESA_SA_CFG
);
109 writel(CESA_SA_CMD_EN_CESA_SA_ACCL0
, engine
->regs
+ CESA_SA_CMD
);
112 static int mv_cesa_ablkcipher_std_process(struct ablkcipher_request
*req
,
115 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
116 struct mv_cesa_ablkcipher_std_req
*sreq
= &creq
->req
.std
;
117 struct mv_cesa_engine
*engine
= sreq
->base
.engine
;
120 len
= sg_pcopy_from_buffer(req
->dst
, creq
->dst_nents
,
121 engine
->sram
+ CESA_SA_DATA_SRAM_OFFSET
,
122 sreq
->size
, sreq
->offset
);
125 if (sreq
->offset
< req
->nbytes
)
131 static int mv_cesa_ablkcipher_process(struct crypto_async_request
*req
,
134 struct ablkcipher_request
*ablkreq
= ablkcipher_request_cast(req
);
135 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(ablkreq
);
136 struct mv_cesa_ablkcipher_std_req
*sreq
= &creq
->req
.std
;
137 struct mv_cesa_engine
*engine
= sreq
->base
.engine
;
140 if (creq
->req
.base
.type
== CESA_DMA_REQ
)
141 ret
= mv_cesa_dma_process(&creq
->req
.dma
, status
);
143 ret
= mv_cesa_ablkcipher_std_process(ablkreq
, status
);
148 memcpy(ablkreq
->info
, engine
->sram
+ CESA_SA_CRYPT_IV_SRAM_OFFSET
,
149 crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(ablkreq
)));
154 static void mv_cesa_ablkcipher_step(struct crypto_async_request
*req
)
156 struct ablkcipher_request
*ablkreq
= ablkcipher_request_cast(req
);
157 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(ablkreq
);
159 if (creq
->req
.base
.type
== CESA_DMA_REQ
)
160 mv_cesa_dma_step(&creq
->req
.dma
);
162 mv_cesa_ablkcipher_std_step(ablkreq
);
166 mv_cesa_ablkcipher_dma_prepare(struct ablkcipher_request
*req
)
168 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
169 struct mv_cesa_tdma_req
*dreq
= &creq
->req
.dma
;
171 mv_cesa_dma_prepare(dreq
, dreq
->base
.engine
);
175 mv_cesa_ablkcipher_std_prepare(struct ablkcipher_request
*req
)
177 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
178 struct mv_cesa_ablkcipher_std_req
*sreq
= &creq
->req
.std
;
179 struct mv_cesa_engine
*engine
= sreq
->base
.engine
;
183 mv_cesa_adjust_op(engine
, &sreq
->op
);
184 memcpy(engine
->sram
, &sreq
->op
, sizeof(sreq
->op
));
187 static inline void mv_cesa_ablkcipher_prepare(struct crypto_async_request
*req
,
188 struct mv_cesa_engine
*engine
)
190 struct ablkcipher_request
*ablkreq
= ablkcipher_request_cast(req
);
191 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(ablkreq
);
192 creq
->req
.base
.engine
= engine
;
194 if (creq
->req
.base
.type
== CESA_DMA_REQ
)
195 mv_cesa_ablkcipher_dma_prepare(ablkreq
);
197 mv_cesa_ablkcipher_std_prepare(ablkreq
);
201 mv_cesa_ablkcipher_req_cleanup(struct crypto_async_request
*req
)
203 struct ablkcipher_request
*ablkreq
= ablkcipher_request_cast(req
);
205 mv_cesa_ablkcipher_cleanup(ablkreq
);
208 static const struct mv_cesa_req_ops mv_cesa_ablkcipher_req_ops
= {
209 .step
= mv_cesa_ablkcipher_step
,
210 .process
= mv_cesa_ablkcipher_process
,
211 .prepare
= mv_cesa_ablkcipher_prepare
,
212 .cleanup
= mv_cesa_ablkcipher_req_cleanup
,
215 static int mv_cesa_ablkcipher_cra_init(struct crypto_tfm
*tfm
)
217 struct mv_cesa_aes_ctx
*ctx
= crypto_tfm_ctx(tfm
);
219 ctx
->base
.ops
= &mv_cesa_ablkcipher_req_ops
;
221 tfm
->crt_ablkcipher
.reqsize
= sizeof(struct mv_cesa_ablkcipher_req
);
226 static int mv_cesa_aes_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
229 struct crypto_tfm
*tfm
= crypto_ablkcipher_tfm(cipher
);
230 struct mv_cesa_aes_ctx
*ctx
= crypto_tfm_ctx(tfm
);
236 ret
= crypto_aes_expand_key(&ctx
->aes
, key
, len
);
238 crypto_ablkcipher_set_flags(cipher
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
242 remaining
= (ctx
->aes
.key_length
- 16) / 4;
243 offset
= ctx
->aes
.key_length
+ 24 - remaining
;
244 for (i
= 0; i
< remaining
; i
++)
245 ctx
->aes
.key_dec
[4 + i
] =
246 cpu_to_le32(ctx
->aes
.key_enc
[offset
+ i
]);
251 static int mv_cesa_des_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
254 struct crypto_tfm
*tfm
= crypto_ablkcipher_tfm(cipher
);
255 struct mv_cesa_des_ctx
*ctx
= crypto_tfm_ctx(tfm
);
256 u32 tmp
[DES_EXPKEY_WORDS
];
259 if (len
!= DES_KEY_SIZE
) {
260 crypto_ablkcipher_set_flags(cipher
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
264 ret
= des_ekey(tmp
, key
);
265 if (!ret
&& (tfm
->crt_flags
& CRYPTO_TFM_REQ_WEAK_KEY
)) {
266 tfm
->crt_flags
|= CRYPTO_TFM_RES_WEAK_KEY
;
270 memcpy(ctx
->key
, key
, DES_KEY_SIZE
);
275 static int mv_cesa_des3_ede_setkey(struct crypto_ablkcipher
*cipher
,
276 const u8
*key
, unsigned int len
)
278 struct crypto_tfm
*tfm
= crypto_ablkcipher_tfm(cipher
);
279 struct mv_cesa_des_ctx
*ctx
= crypto_tfm_ctx(tfm
);
281 if (len
!= DES3_EDE_KEY_SIZE
) {
282 crypto_ablkcipher_set_flags(cipher
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
286 memcpy(ctx
->key
, key
, DES3_EDE_KEY_SIZE
);
291 static int mv_cesa_ablkcipher_dma_req_init(struct ablkcipher_request
*req
,
292 const struct mv_cesa_op_ctx
*op_templ
)
294 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
295 gfp_t flags
= (req
->base
.flags
& CRYPTO_TFM_REQ_MAY_SLEEP
) ?
296 GFP_KERNEL
: GFP_ATOMIC
;
297 struct mv_cesa_tdma_req
*dreq
= &creq
->req
.dma
;
298 struct mv_cesa_ablkcipher_dma_iter iter
;
299 struct mv_cesa_tdma_chain chain
;
300 bool skip_ctx
= false;
303 dreq
->base
.type
= CESA_DMA_REQ
;
304 dreq
->chain
.first
= NULL
;
305 dreq
->chain
.last
= NULL
;
307 if (req
->src
!= req
->dst
) {
308 ret
= dma_map_sg(cesa_dev
->dev
, req
->src
, creq
->src_nents
,
313 ret
= dma_map_sg(cesa_dev
->dev
, req
->dst
, creq
->dst_nents
,
320 ret
= dma_map_sg(cesa_dev
->dev
, req
->src
, creq
->src_nents
,
326 mv_cesa_tdma_desc_iter_init(&chain
);
327 mv_cesa_ablkcipher_req_iter_init(&iter
, req
);
330 struct mv_cesa_op_ctx
*op
;
332 op
= mv_cesa_dma_add_op(&chain
, op_templ
, skip_ctx
, flags
);
339 mv_cesa_set_crypt_op_len(op
, iter
.base
.op_len
);
341 /* Add input transfers */
342 ret
= mv_cesa_dma_add_op_transfers(&chain
, &iter
.base
,
347 /* Add dummy desc to launch the crypto operation */
348 ret
= mv_cesa_dma_add_dummy_launch(&chain
, flags
);
352 /* Add output transfers */
353 ret
= mv_cesa_dma_add_op_transfers(&chain
, &iter
.base
,
358 } while (mv_cesa_ablkcipher_req_iter_next_op(&iter
));
365 mv_cesa_dma_cleanup(dreq
);
366 if (req
->dst
!= req
->src
)
367 dma_unmap_sg(cesa_dev
->dev
, req
->dst
, creq
->dst_nents
,
371 dma_unmap_sg(cesa_dev
->dev
, req
->src
, creq
->src_nents
,
372 req
->dst
!= req
->src
? DMA_TO_DEVICE
: DMA_BIDIRECTIONAL
);
378 mv_cesa_ablkcipher_std_req_init(struct ablkcipher_request
*req
,
379 const struct mv_cesa_op_ctx
*op_templ
)
381 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
382 struct mv_cesa_ablkcipher_std_req
*sreq
= &creq
->req
.std
;
384 sreq
->base
.type
= CESA_STD_REQ
;
385 sreq
->op
= *op_templ
;
386 sreq
->skip_ctx
= false;
391 static int mv_cesa_ablkcipher_req_init(struct ablkcipher_request
*req
,
392 struct mv_cesa_op_ctx
*tmpl
)
394 struct mv_cesa_ablkcipher_req
*creq
= ablkcipher_request_ctx(req
);
395 struct crypto_ablkcipher
*tfm
= crypto_ablkcipher_reqtfm(req
);
396 unsigned int blksize
= crypto_ablkcipher_blocksize(tfm
);
399 if (!IS_ALIGNED(req
->nbytes
, blksize
))
402 creq
->src_nents
= sg_nents_for_len(req
->src
, req
->nbytes
);
403 creq
->dst_nents
= sg_nents_for_len(req
->dst
, req
->nbytes
);
405 mv_cesa_update_op_cfg(tmpl
, CESA_SA_DESC_CFG_OP_CRYPT_ONLY
,
406 CESA_SA_DESC_CFG_OP_MSK
);
408 /* TODO: add a threshold for DMA usage */
409 if (cesa_dev
->caps
->has_tdma
)
410 ret
= mv_cesa_ablkcipher_dma_req_init(req
, tmpl
);
412 ret
= mv_cesa_ablkcipher_std_req_init(req
, tmpl
);
417 static int mv_cesa_des_op(struct ablkcipher_request
*req
,
418 struct mv_cesa_op_ctx
*tmpl
)
420 struct mv_cesa_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
423 mv_cesa_update_op_cfg(tmpl
, CESA_SA_DESC_CFG_CRYPTM_DES
,
424 CESA_SA_DESC_CFG_CRYPTM_MSK
);
426 memcpy(tmpl
->ctx
.blkcipher
.key
, ctx
->key
, DES_KEY_SIZE
);
428 ret
= mv_cesa_ablkcipher_req_init(req
, tmpl
);
432 ret
= mv_cesa_queue_req(&req
->base
);
433 if (mv_cesa_req_needs_cleanup(&req
->base
, ret
))
434 mv_cesa_ablkcipher_cleanup(req
);
439 static int mv_cesa_ecb_des_encrypt(struct ablkcipher_request
*req
)
441 struct mv_cesa_op_ctx tmpl
;
443 mv_cesa_set_op_cfg(&tmpl
,
444 CESA_SA_DESC_CFG_CRYPTCM_ECB
|
445 CESA_SA_DESC_CFG_DIR_ENC
);
447 return mv_cesa_des_op(req
, &tmpl
);
450 static int mv_cesa_ecb_des_decrypt(struct ablkcipher_request
*req
)
452 struct mv_cesa_op_ctx tmpl
;
454 mv_cesa_set_op_cfg(&tmpl
,
455 CESA_SA_DESC_CFG_CRYPTCM_ECB
|
456 CESA_SA_DESC_CFG_DIR_DEC
);
458 return mv_cesa_des_op(req
, &tmpl
);
461 struct crypto_alg mv_cesa_ecb_des_alg
= {
462 .cra_name
= "ecb(des)",
463 .cra_driver_name
= "mv-ecb-des",
465 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
|
466 CRYPTO_ALG_KERN_DRIVER_ONLY
| CRYPTO_ALG_ASYNC
,
467 .cra_blocksize
= DES_BLOCK_SIZE
,
468 .cra_ctxsize
= sizeof(struct mv_cesa_des_ctx
),
470 .cra_type
= &crypto_ablkcipher_type
,
471 .cra_module
= THIS_MODULE
,
472 .cra_init
= mv_cesa_ablkcipher_cra_init
,
475 .min_keysize
= DES_KEY_SIZE
,
476 .max_keysize
= DES_KEY_SIZE
,
477 .setkey
= mv_cesa_des_setkey
,
478 .encrypt
= mv_cesa_ecb_des_encrypt
,
479 .decrypt
= mv_cesa_ecb_des_decrypt
,
484 static int mv_cesa_cbc_des_op(struct ablkcipher_request
*req
,
485 struct mv_cesa_op_ctx
*tmpl
)
487 mv_cesa_update_op_cfg(tmpl
, CESA_SA_DESC_CFG_CRYPTCM_CBC
,
488 CESA_SA_DESC_CFG_CRYPTCM_MSK
);
490 memcpy(tmpl
->ctx
.blkcipher
.iv
, req
->info
, DES_BLOCK_SIZE
);
492 return mv_cesa_des_op(req
, tmpl
);
495 static int mv_cesa_cbc_des_encrypt(struct ablkcipher_request
*req
)
497 struct mv_cesa_op_ctx tmpl
;
499 mv_cesa_set_op_cfg(&tmpl
, CESA_SA_DESC_CFG_DIR_ENC
);
501 return mv_cesa_cbc_des_op(req
, &tmpl
);
504 static int mv_cesa_cbc_des_decrypt(struct ablkcipher_request
*req
)
506 struct mv_cesa_op_ctx tmpl
;
508 mv_cesa_set_op_cfg(&tmpl
, CESA_SA_DESC_CFG_DIR_DEC
);
510 return mv_cesa_cbc_des_op(req
, &tmpl
);
513 struct crypto_alg mv_cesa_cbc_des_alg
= {
514 .cra_name
= "cbc(des)",
515 .cra_driver_name
= "mv-cbc-des",
517 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
|
518 CRYPTO_ALG_KERN_DRIVER_ONLY
| CRYPTO_ALG_ASYNC
,
519 .cra_blocksize
= DES_BLOCK_SIZE
,
520 .cra_ctxsize
= sizeof(struct mv_cesa_des_ctx
),
522 .cra_type
= &crypto_ablkcipher_type
,
523 .cra_module
= THIS_MODULE
,
524 .cra_init
= mv_cesa_ablkcipher_cra_init
,
527 .min_keysize
= DES_KEY_SIZE
,
528 .max_keysize
= DES_KEY_SIZE
,
529 .ivsize
= DES_BLOCK_SIZE
,
530 .setkey
= mv_cesa_des_setkey
,
531 .encrypt
= mv_cesa_cbc_des_encrypt
,
532 .decrypt
= mv_cesa_cbc_des_decrypt
,
537 static int mv_cesa_des3_op(struct ablkcipher_request
*req
,
538 struct mv_cesa_op_ctx
*tmpl
)
540 struct mv_cesa_des3_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
543 mv_cesa_update_op_cfg(tmpl
, CESA_SA_DESC_CFG_CRYPTM_3DES
,
544 CESA_SA_DESC_CFG_CRYPTM_MSK
);
546 memcpy(tmpl
->ctx
.blkcipher
.key
, ctx
->key
, DES3_EDE_KEY_SIZE
);
548 ret
= mv_cesa_ablkcipher_req_init(req
, tmpl
);
552 ret
= mv_cesa_queue_req(&req
->base
);
553 if (mv_cesa_req_needs_cleanup(&req
->base
, ret
))
554 mv_cesa_ablkcipher_cleanup(req
);
559 static int mv_cesa_ecb_des3_ede_encrypt(struct ablkcipher_request
*req
)
561 struct mv_cesa_op_ctx tmpl
;
563 mv_cesa_set_op_cfg(&tmpl
,
564 CESA_SA_DESC_CFG_CRYPTCM_ECB
|
565 CESA_SA_DESC_CFG_3DES_EDE
|
566 CESA_SA_DESC_CFG_DIR_ENC
);
568 return mv_cesa_des3_op(req
, &tmpl
);
571 static int mv_cesa_ecb_des3_ede_decrypt(struct ablkcipher_request
*req
)
573 struct mv_cesa_op_ctx tmpl
;
575 mv_cesa_set_op_cfg(&tmpl
,
576 CESA_SA_DESC_CFG_CRYPTCM_ECB
|
577 CESA_SA_DESC_CFG_3DES_EDE
|
578 CESA_SA_DESC_CFG_DIR_DEC
);
580 return mv_cesa_des3_op(req
, &tmpl
);
583 struct crypto_alg mv_cesa_ecb_des3_ede_alg
= {
584 .cra_name
= "ecb(des3_ede)",
585 .cra_driver_name
= "mv-ecb-des3-ede",
587 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
|
588 CRYPTO_ALG_KERN_DRIVER_ONLY
| CRYPTO_ALG_ASYNC
,
589 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
590 .cra_ctxsize
= sizeof(struct mv_cesa_des3_ctx
),
592 .cra_type
= &crypto_ablkcipher_type
,
593 .cra_module
= THIS_MODULE
,
594 .cra_init
= mv_cesa_ablkcipher_cra_init
,
597 .min_keysize
= DES3_EDE_KEY_SIZE
,
598 .max_keysize
= DES3_EDE_KEY_SIZE
,
599 .ivsize
= DES3_EDE_BLOCK_SIZE
,
600 .setkey
= mv_cesa_des3_ede_setkey
,
601 .encrypt
= mv_cesa_ecb_des3_ede_encrypt
,
602 .decrypt
= mv_cesa_ecb_des3_ede_decrypt
,
607 static int mv_cesa_cbc_des3_op(struct ablkcipher_request
*req
,
608 struct mv_cesa_op_ctx
*tmpl
)
610 memcpy(tmpl
->ctx
.blkcipher
.iv
, req
->info
, DES3_EDE_BLOCK_SIZE
);
612 return mv_cesa_des3_op(req
, tmpl
);
615 static int mv_cesa_cbc_des3_ede_encrypt(struct ablkcipher_request
*req
)
617 struct mv_cesa_op_ctx tmpl
;
619 mv_cesa_set_op_cfg(&tmpl
,
620 CESA_SA_DESC_CFG_CRYPTCM_CBC
|
621 CESA_SA_DESC_CFG_3DES_EDE
|
622 CESA_SA_DESC_CFG_DIR_ENC
);
624 return mv_cesa_cbc_des3_op(req
, &tmpl
);
627 static int mv_cesa_cbc_des3_ede_decrypt(struct ablkcipher_request
*req
)
629 struct mv_cesa_op_ctx tmpl
;
631 mv_cesa_set_op_cfg(&tmpl
,
632 CESA_SA_DESC_CFG_CRYPTCM_CBC
|
633 CESA_SA_DESC_CFG_3DES_EDE
|
634 CESA_SA_DESC_CFG_DIR_DEC
);
636 return mv_cesa_cbc_des3_op(req
, &tmpl
);
639 struct crypto_alg mv_cesa_cbc_des3_ede_alg
= {
640 .cra_name
= "cbc(des3_ede)",
641 .cra_driver_name
= "mv-cbc-des3-ede",
643 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
|
644 CRYPTO_ALG_KERN_DRIVER_ONLY
| CRYPTO_ALG_ASYNC
,
645 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
646 .cra_ctxsize
= sizeof(struct mv_cesa_des3_ctx
),
648 .cra_type
= &crypto_ablkcipher_type
,
649 .cra_module
= THIS_MODULE
,
650 .cra_init
= mv_cesa_ablkcipher_cra_init
,
653 .min_keysize
= DES3_EDE_KEY_SIZE
,
654 .max_keysize
= DES3_EDE_KEY_SIZE
,
655 .ivsize
= DES3_EDE_BLOCK_SIZE
,
656 .setkey
= mv_cesa_des3_ede_setkey
,
657 .encrypt
= mv_cesa_cbc_des3_ede_encrypt
,
658 .decrypt
= mv_cesa_cbc_des3_ede_decrypt
,
663 static int mv_cesa_aes_op(struct ablkcipher_request
*req
,
664 struct mv_cesa_op_ctx
*tmpl
)
666 struct mv_cesa_aes_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
671 cfg
= CESA_SA_DESC_CFG_CRYPTM_AES
;
673 if (mv_cesa_get_op_cfg(tmpl
) & CESA_SA_DESC_CFG_DIR_DEC
)
674 key
= ctx
->aes
.key_dec
;
676 key
= ctx
->aes
.key_enc
;
678 for (i
= 0; i
< ctx
->aes
.key_length
/ sizeof(u32
); i
++)
679 tmpl
->ctx
.blkcipher
.key
[i
] = cpu_to_le32(key
[i
]);
681 if (ctx
->aes
.key_length
== 24)
682 cfg
|= CESA_SA_DESC_CFG_AES_LEN_192
;
683 else if (ctx
->aes
.key_length
== 32)
684 cfg
|= CESA_SA_DESC_CFG_AES_LEN_256
;
686 mv_cesa_update_op_cfg(tmpl
, cfg
,
687 CESA_SA_DESC_CFG_CRYPTM_MSK
|
688 CESA_SA_DESC_CFG_AES_LEN_MSK
);
690 ret
= mv_cesa_ablkcipher_req_init(req
, tmpl
);
694 ret
= mv_cesa_queue_req(&req
->base
);
695 if (mv_cesa_req_needs_cleanup(&req
->base
, ret
))
696 mv_cesa_ablkcipher_cleanup(req
);
701 static int mv_cesa_ecb_aes_encrypt(struct ablkcipher_request
*req
)
703 struct mv_cesa_op_ctx tmpl
;
705 mv_cesa_set_op_cfg(&tmpl
,
706 CESA_SA_DESC_CFG_CRYPTCM_ECB
|
707 CESA_SA_DESC_CFG_DIR_ENC
);
709 return mv_cesa_aes_op(req
, &tmpl
);
712 static int mv_cesa_ecb_aes_decrypt(struct ablkcipher_request
*req
)
714 struct mv_cesa_op_ctx tmpl
;
716 mv_cesa_set_op_cfg(&tmpl
,
717 CESA_SA_DESC_CFG_CRYPTCM_ECB
|
718 CESA_SA_DESC_CFG_DIR_DEC
);
720 return mv_cesa_aes_op(req
, &tmpl
);
723 struct crypto_alg mv_cesa_ecb_aes_alg
= {
724 .cra_name
= "ecb(aes)",
725 .cra_driver_name
= "mv-ecb-aes",
727 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
|
728 CRYPTO_ALG_KERN_DRIVER_ONLY
| CRYPTO_ALG_ASYNC
,
729 .cra_blocksize
= AES_BLOCK_SIZE
,
730 .cra_ctxsize
= sizeof(struct mv_cesa_aes_ctx
),
732 .cra_type
= &crypto_ablkcipher_type
,
733 .cra_module
= THIS_MODULE
,
734 .cra_init
= mv_cesa_ablkcipher_cra_init
,
737 .min_keysize
= AES_MIN_KEY_SIZE
,
738 .max_keysize
= AES_MAX_KEY_SIZE
,
739 .setkey
= mv_cesa_aes_setkey
,
740 .encrypt
= mv_cesa_ecb_aes_encrypt
,
741 .decrypt
= mv_cesa_ecb_aes_decrypt
,
746 static int mv_cesa_cbc_aes_op(struct ablkcipher_request
*req
,
747 struct mv_cesa_op_ctx
*tmpl
)
749 mv_cesa_update_op_cfg(tmpl
, CESA_SA_DESC_CFG_CRYPTCM_CBC
,
750 CESA_SA_DESC_CFG_CRYPTCM_MSK
);
751 memcpy(tmpl
->ctx
.blkcipher
.iv
, req
->info
, AES_BLOCK_SIZE
);
753 return mv_cesa_aes_op(req
, tmpl
);
756 static int mv_cesa_cbc_aes_encrypt(struct ablkcipher_request
*req
)
758 struct mv_cesa_op_ctx tmpl
;
760 mv_cesa_set_op_cfg(&tmpl
, CESA_SA_DESC_CFG_DIR_ENC
);
762 return mv_cesa_cbc_aes_op(req
, &tmpl
);
765 static int mv_cesa_cbc_aes_decrypt(struct ablkcipher_request
*req
)
767 struct mv_cesa_op_ctx tmpl
;
769 mv_cesa_set_op_cfg(&tmpl
, CESA_SA_DESC_CFG_DIR_DEC
);
771 return mv_cesa_cbc_aes_op(req
, &tmpl
);
774 struct crypto_alg mv_cesa_cbc_aes_alg
= {
775 .cra_name
= "cbc(aes)",
776 .cra_driver_name
= "mv-cbc-aes",
778 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
|
779 CRYPTO_ALG_KERN_DRIVER_ONLY
| CRYPTO_ALG_ASYNC
,
780 .cra_blocksize
= AES_BLOCK_SIZE
,
781 .cra_ctxsize
= sizeof(struct mv_cesa_aes_ctx
),
783 .cra_type
= &crypto_ablkcipher_type
,
784 .cra_module
= THIS_MODULE
,
785 .cra_init
= mv_cesa_ablkcipher_cra_init
,
788 .min_keysize
= AES_MIN_KEY_SIZE
,
789 .max_keysize
= AES_MAX_KEY_SIZE
,
790 .ivsize
= AES_BLOCK_SIZE
,
791 .setkey
= mv_cesa_aes_setkey
,
792 .encrypt
= mv_cesa_cbc_aes_encrypt
,
793 .decrypt
= mv_cesa_cbc_aes_decrypt
,