1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Cipher algorithms supported by the CESA: DES, 3DES and AES. 4 * 5 * Author: Boris Brezillon <boris.brezillon@free-electrons.com> 6 * Author: Arnaud Ebalard <arno@natisbad.org> 7 * 8 * This work is based on an initial version written by 9 * Sebastian Andrzej Siewior < sebastian at breakpoint dot cc > 10 */ 11 12 #include <crypto/aes.h> 13 #include <crypto/internal/des.h> 14 15 #include "cesa.h" 16 17 struct mv_cesa_des_ctx { 18 struct mv_cesa_ctx base; 19 u8 key[DES_KEY_SIZE]; 20 }; 21 22 struct mv_cesa_des3_ctx { 23 struct mv_cesa_ctx base; 24 u8 key[DES3_EDE_KEY_SIZE]; 25 }; 26 27 struct mv_cesa_aes_ctx { 28 struct mv_cesa_ctx base; 29 struct crypto_aes_ctx aes; 30 }; 31 32 struct mv_cesa_skcipher_dma_iter { 33 struct mv_cesa_dma_iter base; 34 struct mv_cesa_sg_dma_iter src; 35 struct mv_cesa_sg_dma_iter dst; 36 }; 37 38 static inline void 39 mv_cesa_skcipher_req_iter_init(struct mv_cesa_skcipher_dma_iter *iter, 40 struct skcipher_request *req) 41 { 42 mv_cesa_req_dma_iter_init(&iter->base, req->cryptlen); 43 mv_cesa_sg_dma_iter_init(&iter->src, req->src, DMA_TO_DEVICE); 44 mv_cesa_sg_dma_iter_init(&iter->dst, req->dst, DMA_FROM_DEVICE); 45 } 46 47 static inline bool 48 mv_cesa_skcipher_req_iter_next_op(struct mv_cesa_skcipher_dma_iter *iter) 49 { 50 iter->src.op_offset = 0; 51 iter->dst.op_offset = 0; 52 53 return mv_cesa_req_dma_iter_next_op(&iter->base); 54 } 55 56 static inline void 57 mv_cesa_skcipher_dma_cleanup(struct skcipher_request *req) 58 { 59 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 60 61 if (req->dst != req->src) { 62 dma_unmap_sg(cesa_dev->dev, req->dst, creq->dst_nents, 63 DMA_FROM_DEVICE); 64 dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, 65 DMA_TO_DEVICE); 66 } else { 67 dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, 68 DMA_BIDIRECTIONAL); 69 } 70 mv_cesa_dma_cleanup(&creq->base); 71 } 72 73 static inline void mv_cesa_skcipher_cleanup(struct skcipher_request *req) 74 { 75 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 76 77 if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) 78 mv_cesa_skcipher_dma_cleanup(req); 79 } 80 81 static void mv_cesa_skcipher_std_step(struct skcipher_request *req) 82 { 83 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 84 struct mv_cesa_skcipher_std_req *sreq = &creq->std; 85 struct mv_cesa_engine *engine = creq->base.engine; 86 size_t len = min_t(size_t, req->cryptlen - sreq->offset, 87 CESA_SA_SRAM_PAYLOAD_SIZE); 88 89 mv_cesa_adjust_op(engine, &sreq->op); 90 memcpy_toio(engine->sram, &sreq->op, sizeof(sreq->op)); 91 92 len = sg_pcopy_to_buffer(req->src, creq->src_nents, 93 engine->sram + CESA_SA_DATA_SRAM_OFFSET, 94 len, sreq->offset); 95 96 sreq->size = len; 97 mv_cesa_set_crypt_op_len(&sreq->op, len); 98 99 /* FIXME: only update enc_len field */ 100 if (!sreq->skip_ctx) { 101 memcpy_toio(engine->sram, &sreq->op, sizeof(sreq->op)); 102 sreq->skip_ctx = true; 103 } else { 104 memcpy_toio(engine->sram, &sreq->op, sizeof(sreq->op.desc)); 105 } 106 107 mv_cesa_set_int_mask(engine, CESA_SA_INT_ACCEL0_DONE); 108 writel_relaxed(CESA_SA_CFG_PARA_DIS, engine->regs + CESA_SA_CFG); 109 WARN_ON(readl(engine->regs + CESA_SA_CMD) & 110 CESA_SA_CMD_EN_CESA_SA_ACCL0); 111 writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs + CESA_SA_CMD); 112 } 113 114 static int mv_cesa_skcipher_std_process(struct skcipher_request *req, 115 u32 status) 116 { 117 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 118 struct mv_cesa_skcipher_std_req *sreq = &creq->std; 119 struct mv_cesa_engine *engine = creq->base.engine; 120 size_t len; 121 122 len = sg_pcopy_from_buffer(req->dst, creq->dst_nents, 123 engine->sram + CESA_SA_DATA_SRAM_OFFSET, 124 sreq->size, sreq->offset); 125 126 sreq->offset += len; 127 if (sreq->offset < req->cryptlen) 128 return -EINPROGRESS; 129 130 return 0; 131 } 132 133 static int mv_cesa_skcipher_process(struct crypto_async_request *req, 134 u32 status) 135 { 136 struct skcipher_request *skreq = skcipher_request_cast(req); 137 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(skreq); 138 struct mv_cesa_req *basereq = &creq->base; 139 140 if (mv_cesa_req_get_type(basereq) == CESA_STD_REQ) 141 return mv_cesa_skcipher_std_process(skreq, status); 142 143 return mv_cesa_dma_process(basereq, status); 144 } 145 146 static void mv_cesa_skcipher_step(struct crypto_async_request *req) 147 { 148 struct skcipher_request *skreq = skcipher_request_cast(req); 149 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(skreq); 150 151 if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) 152 mv_cesa_dma_step(&creq->base); 153 else 154 mv_cesa_skcipher_std_step(skreq); 155 } 156 157 static inline void 158 mv_cesa_skcipher_dma_prepare(struct skcipher_request *req) 159 { 160 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 161 struct mv_cesa_req *basereq = &creq->base; 162 163 mv_cesa_dma_prepare(basereq, basereq->engine); 164 } 165 166 static inline void 167 mv_cesa_skcipher_std_prepare(struct skcipher_request *req) 168 { 169 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 170 struct mv_cesa_skcipher_std_req *sreq = &creq->std; 171 172 sreq->size = 0; 173 sreq->offset = 0; 174 } 175 176 static inline void mv_cesa_skcipher_prepare(struct crypto_async_request *req, 177 struct mv_cesa_engine *engine) 178 { 179 struct skcipher_request *skreq = skcipher_request_cast(req); 180 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(skreq); 181 182 creq->base.engine = engine; 183 184 if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) 185 mv_cesa_skcipher_dma_prepare(skreq); 186 else 187 mv_cesa_skcipher_std_prepare(skreq); 188 } 189 190 static inline void 191 mv_cesa_skcipher_req_cleanup(struct crypto_async_request *req) 192 { 193 struct skcipher_request *skreq = skcipher_request_cast(req); 194 195 mv_cesa_skcipher_cleanup(skreq); 196 } 197 198 static void 199 mv_cesa_skcipher_complete(struct crypto_async_request *req) 200 { 201 struct skcipher_request *skreq = skcipher_request_cast(req); 202 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(skreq); 203 struct mv_cesa_engine *engine = creq->base.engine; 204 unsigned int ivsize; 205 206 atomic_sub(skreq->cryptlen, &engine->load); 207 ivsize = crypto_skcipher_ivsize(crypto_skcipher_reqtfm(skreq)); 208 209 if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) { 210 struct mv_cesa_req *basereq; 211 212 basereq = &creq->base; 213 memcpy(skreq->iv, basereq->chain.last->op->ctx.skcipher.iv, 214 ivsize); 215 } else { 216 memcpy_fromio(skreq->iv, 217 engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET, 218 ivsize); 219 } 220 } 221 222 static const struct mv_cesa_req_ops mv_cesa_skcipher_req_ops = { 223 .step = mv_cesa_skcipher_step, 224 .process = mv_cesa_skcipher_process, 225 .cleanup = mv_cesa_skcipher_req_cleanup, 226 .complete = mv_cesa_skcipher_complete, 227 }; 228 229 static void mv_cesa_skcipher_cra_exit(struct crypto_tfm *tfm) 230 { 231 void *ctx = crypto_tfm_ctx(tfm); 232 233 memzero_explicit(ctx, tfm->__crt_alg->cra_ctxsize); 234 } 235 236 static int mv_cesa_skcipher_cra_init(struct crypto_tfm *tfm) 237 { 238 struct mv_cesa_ctx *ctx = crypto_tfm_ctx(tfm); 239 240 ctx->ops = &mv_cesa_skcipher_req_ops; 241 242 crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 243 sizeof(struct mv_cesa_skcipher_req)); 244 245 return 0; 246 } 247 248 static int mv_cesa_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 249 unsigned int len) 250 { 251 struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 252 struct mv_cesa_aes_ctx *ctx = crypto_tfm_ctx(tfm); 253 int remaining; 254 int offset; 255 int ret; 256 int i; 257 258 ret = aes_expandkey(&ctx->aes, key, len); 259 if (ret) 260 return ret; 261 262 remaining = (ctx->aes.key_length - 16) / 4; 263 offset = ctx->aes.key_length + 24 - remaining; 264 for (i = 0; i < remaining; i++) 265 ctx->aes.key_dec[4 + i] = 266 cpu_to_le32(ctx->aes.key_enc[offset + i]); 267 268 return 0; 269 } 270 271 static int mv_cesa_des_setkey(struct crypto_skcipher *cipher, const u8 *key, 272 unsigned int len) 273 { 274 struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher); 275 int err; 276 277 err = verify_skcipher_des_key(cipher, key); 278 if (err) 279 return err; 280 281 memcpy(ctx->key, key, DES_KEY_SIZE); 282 283 return 0; 284 } 285 286 static int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher, 287 const u8 *key, unsigned int len) 288 { 289 struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher); 290 int err; 291 292 err = verify_skcipher_des3_key(cipher, key); 293 if (err) 294 return err; 295 296 memcpy(ctx->key, key, DES3_EDE_KEY_SIZE); 297 298 return 0; 299 } 300 301 static int mv_cesa_skcipher_dma_req_init(struct skcipher_request *req, 302 const struct mv_cesa_op_ctx *op_templ) 303 { 304 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 305 gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 306 GFP_KERNEL : GFP_ATOMIC; 307 struct mv_cesa_req *basereq = &creq->base; 308 struct mv_cesa_skcipher_dma_iter iter; 309 bool skip_ctx = false; 310 int ret; 311 312 basereq->chain.first = NULL; 313 basereq->chain.last = NULL; 314 315 if (req->src != req->dst) { 316 ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents, 317 DMA_TO_DEVICE); 318 if (!ret) 319 return -ENOMEM; 320 321 ret = dma_map_sg(cesa_dev->dev, req->dst, creq->dst_nents, 322 DMA_FROM_DEVICE); 323 if (!ret) { 324 ret = -ENOMEM; 325 goto err_unmap_src; 326 } 327 } else { 328 ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents, 329 DMA_BIDIRECTIONAL); 330 if (!ret) 331 return -ENOMEM; 332 } 333 334 mv_cesa_tdma_desc_iter_init(&basereq->chain); 335 mv_cesa_skcipher_req_iter_init(&iter, req); 336 337 do { 338 struct mv_cesa_op_ctx *op; 339 340 op = mv_cesa_dma_add_op(&basereq->chain, op_templ, skip_ctx, 341 flags); 342 if (IS_ERR(op)) { 343 ret = PTR_ERR(op); 344 goto err_free_tdma; 345 } 346 skip_ctx = true; 347 348 mv_cesa_set_crypt_op_len(op, iter.base.op_len); 349 350 /* Add input transfers */ 351 ret = mv_cesa_dma_add_op_transfers(&basereq->chain, &iter.base, 352 &iter.src, flags); 353 if (ret) 354 goto err_free_tdma; 355 356 /* Add dummy desc to launch the crypto operation */ 357 ret = mv_cesa_dma_add_dummy_launch(&basereq->chain, flags); 358 if (ret) 359 goto err_free_tdma; 360 361 /* Add output transfers */ 362 ret = mv_cesa_dma_add_op_transfers(&basereq->chain, &iter.base, 363 &iter.dst, flags); 364 if (ret) 365 goto err_free_tdma; 366 367 } while (mv_cesa_skcipher_req_iter_next_op(&iter)); 368 369 /* Add output data for IV */ 370 ret = mv_cesa_dma_add_result_op(&basereq->chain, 371 CESA_SA_CFG_SRAM_OFFSET, 372 CESA_SA_DATA_SRAM_OFFSET, 373 CESA_TDMA_SRC_IN_SRAM, flags); 374 375 if (ret) 376 goto err_free_tdma; 377 378 basereq->chain.last->flags |= CESA_TDMA_END_OF_REQ; 379 380 return 0; 381 382 err_free_tdma: 383 mv_cesa_dma_cleanup(basereq); 384 if (req->dst != req->src) 385 dma_unmap_sg(cesa_dev->dev, req->dst, creq->dst_nents, 386 DMA_FROM_DEVICE); 387 388 err_unmap_src: 389 dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, 390 req->dst != req->src ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL); 391 392 return ret; 393 } 394 395 static inline int 396 mv_cesa_skcipher_std_req_init(struct skcipher_request *req, 397 const struct mv_cesa_op_ctx *op_templ) 398 { 399 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 400 struct mv_cesa_skcipher_std_req *sreq = &creq->std; 401 struct mv_cesa_req *basereq = &creq->base; 402 403 sreq->op = *op_templ; 404 sreq->skip_ctx = false; 405 basereq->chain.first = NULL; 406 basereq->chain.last = NULL; 407 408 return 0; 409 } 410 411 static int mv_cesa_skcipher_req_init(struct skcipher_request *req, 412 struct mv_cesa_op_ctx *tmpl) 413 { 414 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 415 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 416 unsigned int blksize = crypto_skcipher_blocksize(tfm); 417 int ret; 418 419 if (!IS_ALIGNED(req->cryptlen, blksize)) 420 return -EINVAL; 421 422 creq->src_nents = sg_nents_for_len(req->src, req->cryptlen); 423 if (creq->src_nents < 0) { 424 dev_err(cesa_dev->dev, "Invalid number of src SG"); 425 return creq->src_nents; 426 } 427 creq->dst_nents = sg_nents_for_len(req->dst, req->cryptlen); 428 if (creq->dst_nents < 0) { 429 dev_err(cesa_dev->dev, "Invalid number of dst SG"); 430 return creq->dst_nents; 431 } 432 433 mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_OP_CRYPT_ONLY, 434 CESA_SA_DESC_CFG_OP_MSK); 435 436 if (cesa_dev->caps->has_tdma) 437 ret = mv_cesa_skcipher_dma_req_init(req, tmpl); 438 else 439 ret = mv_cesa_skcipher_std_req_init(req, tmpl); 440 441 return ret; 442 } 443 444 static int mv_cesa_skcipher_queue_req(struct skcipher_request *req, 445 struct mv_cesa_op_ctx *tmpl) 446 { 447 int ret; 448 struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 449 struct mv_cesa_engine *engine; 450 451 ret = mv_cesa_skcipher_req_init(req, tmpl); 452 if (ret) 453 return ret; 454 455 engine = mv_cesa_select_engine(req->cryptlen); 456 mv_cesa_skcipher_prepare(&req->base, engine); 457 458 ret = mv_cesa_queue_req(&req->base, &creq->base); 459 460 if (mv_cesa_req_needs_cleanup(&req->base, ret)) 461 mv_cesa_skcipher_cleanup(req); 462 463 return ret; 464 } 465 466 static int mv_cesa_des_op(struct skcipher_request *req, 467 struct mv_cesa_op_ctx *tmpl) 468 { 469 struct mv_cesa_des_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 470 471 mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTM_DES, 472 CESA_SA_DESC_CFG_CRYPTM_MSK); 473 474 memcpy(tmpl->ctx.skcipher.key, ctx->key, DES_KEY_SIZE); 475 476 return mv_cesa_skcipher_queue_req(req, tmpl); 477 } 478 479 static int mv_cesa_ecb_des_encrypt(struct skcipher_request *req) 480 { 481 struct mv_cesa_op_ctx tmpl; 482 483 mv_cesa_set_op_cfg(&tmpl, 484 CESA_SA_DESC_CFG_CRYPTCM_ECB | 485 CESA_SA_DESC_CFG_DIR_ENC); 486 487 return mv_cesa_des_op(req, &tmpl); 488 } 489 490 static int mv_cesa_ecb_des_decrypt(struct skcipher_request *req) 491 { 492 struct mv_cesa_op_ctx tmpl; 493 494 mv_cesa_set_op_cfg(&tmpl, 495 CESA_SA_DESC_CFG_CRYPTCM_ECB | 496 CESA_SA_DESC_CFG_DIR_DEC); 497 498 return mv_cesa_des_op(req, &tmpl); 499 } 500 501 struct skcipher_alg mv_cesa_ecb_des_alg = { 502 .setkey = mv_cesa_des_setkey, 503 .encrypt = mv_cesa_ecb_des_encrypt, 504 .decrypt = mv_cesa_ecb_des_decrypt, 505 .min_keysize = DES_KEY_SIZE, 506 .max_keysize = DES_KEY_SIZE, 507 .base = { 508 .cra_name = "ecb(des)", 509 .cra_driver_name = "mv-ecb-des", 510 .cra_priority = 300, 511 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 512 CRYPTO_ALG_ALLOCATES_MEMORY, 513 .cra_blocksize = DES_BLOCK_SIZE, 514 .cra_ctxsize = sizeof(struct mv_cesa_des_ctx), 515 .cra_alignmask = 0, 516 .cra_module = THIS_MODULE, 517 .cra_init = mv_cesa_skcipher_cra_init, 518 .cra_exit = mv_cesa_skcipher_cra_exit, 519 }, 520 }; 521 522 static int mv_cesa_cbc_des_op(struct skcipher_request *req, 523 struct mv_cesa_op_ctx *tmpl) 524 { 525 mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTCM_CBC, 526 CESA_SA_DESC_CFG_CRYPTCM_MSK); 527 528 memcpy(tmpl->ctx.skcipher.iv, req->iv, DES_BLOCK_SIZE); 529 530 return mv_cesa_des_op(req, tmpl); 531 } 532 533 static int mv_cesa_cbc_des_encrypt(struct skcipher_request *req) 534 { 535 struct mv_cesa_op_ctx tmpl; 536 537 mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_DIR_ENC); 538 539 return mv_cesa_cbc_des_op(req, &tmpl); 540 } 541 542 static int mv_cesa_cbc_des_decrypt(struct skcipher_request *req) 543 { 544 struct mv_cesa_op_ctx tmpl; 545 546 mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_DIR_DEC); 547 548 return mv_cesa_cbc_des_op(req, &tmpl); 549 } 550 551 struct skcipher_alg mv_cesa_cbc_des_alg = { 552 .setkey = mv_cesa_des_setkey, 553 .encrypt = mv_cesa_cbc_des_encrypt, 554 .decrypt = mv_cesa_cbc_des_decrypt, 555 .min_keysize = DES_KEY_SIZE, 556 .max_keysize = DES_KEY_SIZE, 557 .ivsize = DES_BLOCK_SIZE, 558 .base = { 559 .cra_name = "cbc(des)", 560 .cra_driver_name = "mv-cbc-des", 561 .cra_priority = 300, 562 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 563 CRYPTO_ALG_ALLOCATES_MEMORY, 564 .cra_blocksize = DES_BLOCK_SIZE, 565 .cra_ctxsize = sizeof(struct mv_cesa_des_ctx), 566 .cra_alignmask = 0, 567 .cra_module = THIS_MODULE, 568 .cra_init = mv_cesa_skcipher_cra_init, 569 .cra_exit = mv_cesa_skcipher_cra_exit, 570 }, 571 }; 572 573 static int mv_cesa_des3_op(struct skcipher_request *req, 574 struct mv_cesa_op_ctx *tmpl) 575 { 576 struct mv_cesa_des3_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 577 578 mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTM_3DES, 579 CESA_SA_DESC_CFG_CRYPTM_MSK); 580 581 memcpy(tmpl->ctx.skcipher.key, ctx->key, DES3_EDE_KEY_SIZE); 582 583 return mv_cesa_skcipher_queue_req(req, tmpl); 584 } 585 586 static int mv_cesa_ecb_des3_ede_encrypt(struct skcipher_request *req) 587 { 588 struct mv_cesa_op_ctx tmpl; 589 590 mv_cesa_set_op_cfg(&tmpl, 591 CESA_SA_DESC_CFG_CRYPTCM_ECB | 592 CESA_SA_DESC_CFG_3DES_EDE | 593 CESA_SA_DESC_CFG_DIR_ENC); 594 595 return mv_cesa_des3_op(req, &tmpl); 596 } 597 598 static int mv_cesa_ecb_des3_ede_decrypt(struct skcipher_request *req) 599 { 600 struct mv_cesa_op_ctx tmpl; 601 602 mv_cesa_set_op_cfg(&tmpl, 603 CESA_SA_DESC_CFG_CRYPTCM_ECB | 604 CESA_SA_DESC_CFG_3DES_EDE | 605 CESA_SA_DESC_CFG_DIR_DEC); 606 607 return mv_cesa_des3_op(req, &tmpl); 608 } 609 610 struct skcipher_alg mv_cesa_ecb_des3_ede_alg = { 611 .setkey = mv_cesa_des3_ede_setkey, 612 .encrypt = mv_cesa_ecb_des3_ede_encrypt, 613 .decrypt = mv_cesa_ecb_des3_ede_decrypt, 614 .min_keysize = DES3_EDE_KEY_SIZE, 615 .max_keysize = DES3_EDE_KEY_SIZE, 616 .ivsize = DES3_EDE_BLOCK_SIZE, 617 .base = { 618 .cra_name = "ecb(des3_ede)", 619 .cra_driver_name = "mv-ecb-des3-ede", 620 .cra_priority = 300, 621 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 622 CRYPTO_ALG_ALLOCATES_MEMORY, 623 .cra_blocksize = DES3_EDE_BLOCK_SIZE, 624 .cra_ctxsize = sizeof(struct mv_cesa_des3_ctx), 625 .cra_alignmask = 0, 626 .cra_module = THIS_MODULE, 627 .cra_init = mv_cesa_skcipher_cra_init, 628 .cra_exit = mv_cesa_skcipher_cra_exit, 629 }, 630 }; 631 632 static int mv_cesa_cbc_des3_op(struct skcipher_request *req, 633 struct mv_cesa_op_ctx *tmpl) 634 { 635 memcpy(tmpl->ctx.skcipher.iv, req->iv, DES3_EDE_BLOCK_SIZE); 636 637 return mv_cesa_des3_op(req, tmpl); 638 } 639 640 static int mv_cesa_cbc_des3_ede_encrypt(struct skcipher_request *req) 641 { 642 struct mv_cesa_op_ctx tmpl; 643 644 mv_cesa_set_op_cfg(&tmpl, 645 CESA_SA_DESC_CFG_CRYPTCM_CBC | 646 CESA_SA_DESC_CFG_3DES_EDE | 647 CESA_SA_DESC_CFG_DIR_ENC); 648 649 return mv_cesa_cbc_des3_op(req, &tmpl); 650 } 651 652 static int mv_cesa_cbc_des3_ede_decrypt(struct skcipher_request *req) 653 { 654 struct mv_cesa_op_ctx tmpl; 655 656 mv_cesa_set_op_cfg(&tmpl, 657 CESA_SA_DESC_CFG_CRYPTCM_CBC | 658 CESA_SA_DESC_CFG_3DES_EDE | 659 CESA_SA_DESC_CFG_DIR_DEC); 660 661 return mv_cesa_cbc_des3_op(req, &tmpl); 662 } 663 664 struct skcipher_alg mv_cesa_cbc_des3_ede_alg = { 665 .setkey = mv_cesa_des3_ede_setkey, 666 .encrypt = mv_cesa_cbc_des3_ede_encrypt, 667 .decrypt = mv_cesa_cbc_des3_ede_decrypt, 668 .min_keysize = DES3_EDE_KEY_SIZE, 669 .max_keysize = DES3_EDE_KEY_SIZE, 670 .ivsize = DES3_EDE_BLOCK_SIZE, 671 .base = { 672 .cra_name = "cbc(des3_ede)", 673 .cra_driver_name = "mv-cbc-des3-ede", 674 .cra_priority = 300, 675 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 676 CRYPTO_ALG_ALLOCATES_MEMORY, 677 .cra_blocksize = DES3_EDE_BLOCK_SIZE, 678 .cra_ctxsize = sizeof(struct mv_cesa_des3_ctx), 679 .cra_alignmask = 0, 680 .cra_module = THIS_MODULE, 681 .cra_init = mv_cesa_skcipher_cra_init, 682 .cra_exit = mv_cesa_skcipher_cra_exit, 683 }, 684 }; 685 686 static int mv_cesa_aes_op(struct skcipher_request *req, 687 struct mv_cesa_op_ctx *tmpl) 688 { 689 struct mv_cesa_aes_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 690 int i; 691 u32 *key; 692 u32 cfg; 693 694 cfg = CESA_SA_DESC_CFG_CRYPTM_AES; 695 696 if (mv_cesa_get_op_cfg(tmpl) & CESA_SA_DESC_CFG_DIR_DEC) 697 key = ctx->aes.key_dec; 698 else 699 key = ctx->aes.key_enc; 700 701 for (i = 0; i < ctx->aes.key_length / sizeof(u32); i++) 702 tmpl->ctx.skcipher.key[i] = cpu_to_le32(key[i]); 703 704 if (ctx->aes.key_length == 24) 705 cfg |= CESA_SA_DESC_CFG_AES_LEN_192; 706 else if (ctx->aes.key_length == 32) 707 cfg |= CESA_SA_DESC_CFG_AES_LEN_256; 708 709 mv_cesa_update_op_cfg(tmpl, cfg, 710 CESA_SA_DESC_CFG_CRYPTM_MSK | 711 CESA_SA_DESC_CFG_AES_LEN_MSK); 712 713 return mv_cesa_skcipher_queue_req(req, tmpl); 714 } 715 716 static int mv_cesa_ecb_aes_encrypt(struct skcipher_request *req) 717 { 718 struct mv_cesa_op_ctx tmpl; 719 720 mv_cesa_set_op_cfg(&tmpl, 721 CESA_SA_DESC_CFG_CRYPTCM_ECB | 722 CESA_SA_DESC_CFG_DIR_ENC); 723 724 return mv_cesa_aes_op(req, &tmpl); 725 } 726 727 static int mv_cesa_ecb_aes_decrypt(struct skcipher_request *req) 728 { 729 struct mv_cesa_op_ctx tmpl; 730 731 mv_cesa_set_op_cfg(&tmpl, 732 CESA_SA_DESC_CFG_CRYPTCM_ECB | 733 CESA_SA_DESC_CFG_DIR_DEC); 734 735 return mv_cesa_aes_op(req, &tmpl); 736 } 737 738 struct skcipher_alg mv_cesa_ecb_aes_alg = { 739 .setkey = mv_cesa_aes_setkey, 740 .encrypt = mv_cesa_ecb_aes_encrypt, 741 .decrypt = mv_cesa_ecb_aes_decrypt, 742 .min_keysize = AES_MIN_KEY_SIZE, 743 .max_keysize = AES_MAX_KEY_SIZE, 744 .base = { 745 .cra_name = "ecb(aes)", 746 .cra_driver_name = "mv-ecb-aes", 747 .cra_priority = 300, 748 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 749 CRYPTO_ALG_ALLOCATES_MEMORY, 750 .cra_blocksize = AES_BLOCK_SIZE, 751 .cra_ctxsize = sizeof(struct mv_cesa_aes_ctx), 752 .cra_alignmask = 0, 753 .cra_module = THIS_MODULE, 754 .cra_init = mv_cesa_skcipher_cra_init, 755 .cra_exit = mv_cesa_skcipher_cra_exit, 756 }, 757 }; 758 759 static int mv_cesa_cbc_aes_op(struct skcipher_request *req, 760 struct mv_cesa_op_ctx *tmpl) 761 { 762 mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTCM_CBC, 763 CESA_SA_DESC_CFG_CRYPTCM_MSK); 764 memcpy(tmpl->ctx.skcipher.iv, req->iv, AES_BLOCK_SIZE); 765 766 return mv_cesa_aes_op(req, tmpl); 767 } 768 769 static int mv_cesa_cbc_aes_encrypt(struct skcipher_request *req) 770 { 771 struct mv_cesa_op_ctx tmpl; 772 773 mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_DIR_ENC); 774 775 return mv_cesa_cbc_aes_op(req, &tmpl); 776 } 777 778 static int mv_cesa_cbc_aes_decrypt(struct skcipher_request *req) 779 { 780 struct mv_cesa_op_ctx tmpl; 781 782 mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_DIR_DEC); 783 784 return mv_cesa_cbc_aes_op(req, &tmpl); 785 } 786 787 struct skcipher_alg mv_cesa_cbc_aes_alg = { 788 .setkey = mv_cesa_aes_setkey, 789 .encrypt = mv_cesa_cbc_aes_encrypt, 790 .decrypt = mv_cesa_cbc_aes_decrypt, 791 .min_keysize = AES_MIN_KEY_SIZE, 792 .max_keysize = AES_MAX_KEY_SIZE, 793 .ivsize = AES_BLOCK_SIZE, 794 .base = { 795 .cra_name = "cbc(aes)", 796 .cra_driver_name = "mv-cbc-aes", 797 .cra_priority = 300, 798 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 799 CRYPTO_ALG_ALLOCATES_MEMORY, 800 .cra_blocksize = AES_BLOCK_SIZE, 801 .cra_ctxsize = sizeof(struct mv_cesa_aes_ctx), 802 .cra_alignmask = 0, 803 .cra_module = THIS_MODULE, 804 .cra_init = mv_cesa_skcipher_cra_init, 805 .cra_exit = mv_cesa_skcipher_cra_exit, 806 }, 807 }; 808