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