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