18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Cipher algorithms supported by the CESA: DES, 3DES and AES. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Author: Boris Brezillon <boris.brezillon@free-electrons.com> 68c2ecf20Sopenharmony_ci * Author: Arnaud Ebalard <arno@natisbad.org> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This work is based on an initial version written by 98c2ecf20Sopenharmony_ci * Sebastian Andrzej Siewior < sebastian at breakpoint dot cc > 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <crypto/aes.h> 138c2ecf20Sopenharmony_ci#include <crypto/internal/des.h> 148c2ecf20Sopenharmony_ci#include <linux/device.h> 158c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include "cesa.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistruct mv_cesa_des_ctx { 208c2ecf20Sopenharmony_ci struct mv_cesa_ctx base; 218c2ecf20Sopenharmony_ci u8 key[DES_KEY_SIZE]; 228c2ecf20Sopenharmony_ci}; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistruct mv_cesa_des3_ctx { 258c2ecf20Sopenharmony_ci struct mv_cesa_ctx base; 268c2ecf20Sopenharmony_ci u8 key[DES3_EDE_KEY_SIZE]; 278c2ecf20Sopenharmony_ci}; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistruct mv_cesa_aes_ctx { 308c2ecf20Sopenharmony_ci struct mv_cesa_ctx base; 318c2ecf20Sopenharmony_ci struct crypto_aes_ctx aes; 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistruct mv_cesa_skcipher_dma_iter { 358c2ecf20Sopenharmony_ci struct mv_cesa_dma_iter base; 368c2ecf20Sopenharmony_ci struct mv_cesa_sg_dma_iter src; 378c2ecf20Sopenharmony_ci struct mv_cesa_sg_dma_iter dst; 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic inline void 418c2ecf20Sopenharmony_cimv_cesa_skcipher_req_iter_init(struct mv_cesa_skcipher_dma_iter *iter, 428c2ecf20Sopenharmony_ci struct skcipher_request *req) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci mv_cesa_req_dma_iter_init(&iter->base, req->cryptlen); 458c2ecf20Sopenharmony_ci mv_cesa_sg_dma_iter_init(&iter->src, req->src, DMA_TO_DEVICE); 468c2ecf20Sopenharmony_ci mv_cesa_sg_dma_iter_init(&iter->dst, req->dst, DMA_FROM_DEVICE); 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic inline bool 508c2ecf20Sopenharmony_cimv_cesa_skcipher_req_iter_next_op(struct mv_cesa_skcipher_dma_iter *iter) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci iter->src.op_offset = 0; 538c2ecf20Sopenharmony_ci iter->dst.op_offset = 0; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci return mv_cesa_req_dma_iter_next_op(&iter->base); 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic inline void 598c2ecf20Sopenharmony_cimv_cesa_skcipher_dma_cleanup(struct skcipher_request *req) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci if (req->dst != req->src) { 648c2ecf20Sopenharmony_ci dma_unmap_sg(cesa_dev->dev, req->dst, creq->dst_nents, 658c2ecf20Sopenharmony_ci DMA_FROM_DEVICE); 668c2ecf20Sopenharmony_ci dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, 678c2ecf20Sopenharmony_ci DMA_TO_DEVICE); 688c2ecf20Sopenharmony_ci } else { 698c2ecf20Sopenharmony_ci dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, 708c2ecf20Sopenharmony_ci DMA_BIDIRECTIONAL); 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci mv_cesa_dma_cleanup(&creq->base); 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic inline void mv_cesa_skcipher_cleanup(struct skcipher_request *req) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) 808c2ecf20Sopenharmony_ci mv_cesa_skcipher_dma_cleanup(req); 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic void mv_cesa_skcipher_std_step(struct skcipher_request *req) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 868c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_std_req *sreq = &creq->std; 878c2ecf20Sopenharmony_ci struct mv_cesa_engine *engine = creq->base.engine; 888c2ecf20Sopenharmony_ci size_t len = min_t(size_t, req->cryptlen - sreq->offset, 898c2ecf20Sopenharmony_ci CESA_SA_SRAM_PAYLOAD_SIZE); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci mv_cesa_adjust_op(engine, &sreq->op); 928c2ecf20Sopenharmony_ci memcpy_toio(engine->sram, &sreq->op, sizeof(sreq->op)); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci len = sg_pcopy_to_buffer(req->src, creq->src_nents, 958c2ecf20Sopenharmony_ci engine->sram + CESA_SA_DATA_SRAM_OFFSET, 968c2ecf20Sopenharmony_ci len, sreq->offset); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci sreq->size = len; 998c2ecf20Sopenharmony_ci mv_cesa_set_crypt_op_len(&sreq->op, len); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci /* FIXME: only update enc_len field */ 1028c2ecf20Sopenharmony_ci if (!sreq->skip_ctx) { 1038c2ecf20Sopenharmony_ci memcpy_toio(engine->sram, &sreq->op, sizeof(sreq->op)); 1048c2ecf20Sopenharmony_ci sreq->skip_ctx = true; 1058c2ecf20Sopenharmony_ci } else { 1068c2ecf20Sopenharmony_ci memcpy_toio(engine->sram, &sreq->op, sizeof(sreq->op.desc)); 1078c2ecf20Sopenharmony_ci } 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci mv_cesa_set_int_mask(engine, CESA_SA_INT_ACCEL0_DONE); 1108c2ecf20Sopenharmony_ci writel_relaxed(CESA_SA_CFG_PARA_DIS, engine->regs + CESA_SA_CFG); 1118c2ecf20Sopenharmony_ci WARN_ON(readl(engine->regs + CESA_SA_CMD) & 1128c2ecf20Sopenharmony_ci CESA_SA_CMD_EN_CESA_SA_ACCL0); 1138c2ecf20Sopenharmony_ci writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs + CESA_SA_CMD); 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic int mv_cesa_skcipher_std_process(struct skcipher_request *req, 1178c2ecf20Sopenharmony_ci u32 status) 1188c2ecf20Sopenharmony_ci{ 1198c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 1208c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_std_req *sreq = &creq->std; 1218c2ecf20Sopenharmony_ci struct mv_cesa_engine *engine = creq->base.engine; 1228c2ecf20Sopenharmony_ci size_t len; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci len = sg_pcopy_from_buffer(req->dst, creq->dst_nents, 1258c2ecf20Sopenharmony_ci engine->sram + CESA_SA_DATA_SRAM_OFFSET, 1268c2ecf20Sopenharmony_ci sreq->size, sreq->offset); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci sreq->offset += len; 1298c2ecf20Sopenharmony_ci if (sreq->offset < req->cryptlen) 1308c2ecf20Sopenharmony_ci return -EINPROGRESS; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci return 0; 1338c2ecf20Sopenharmony_ci} 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_cistatic int mv_cesa_skcipher_process(struct crypto_async_request *req, 1368c2ecf20Sopenharmony_ci u32 status) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci struct skcipher_request *skreq = skcipher_request_cast(req); 1398c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(skreq); 1408c2ecf20Sopenharmony_ci struct mv_cesa_req *basereq = &creq->base; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci if (mv_cesa_req_get_type(basereq) == CESA_STD_REQ) 1438c2ecf20Sopenharmony_ci return mv_cesa_skcipher_std_process(skreq, status); 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci return mv_cesa_dma_process(basereq, status); 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic void mv_cesa_skcipher_step(struct crypto_async_request *req) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci struct skcipher_request *skreq = skcipher_request_cast(req); 1518c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(skreq); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) 1548c2ecf20Sopenharmony_ci mv_cesa_dma_step(&creq->base); 1558c2ecf20Sopenharmony_ci else 1568c2ecf20Sopenharmony_ci mv_cesa_skcipher_std_step(skreq); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic inline void 1608c2ecf20Sopenharmony_cimv_cesa_skcipher_dma_prepare(struct skcipher_request *req) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 1638c2ecf20Sopenharmony_ci struct mv_cesa_req *basereq = &creq->base; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci mv_cesa_dma_prepare(basereq, basereq->engine); 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistatic inline void 1698c2ecf20Sopenharmony_cimv_cesa_skcipher_std_prepare(struct skcipher_request *req) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 1728c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_std_req *sreq = &creq->std; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci sreq->size = 0; 1758c2ecf20Sopenharmony_ci sreq->offset = 0; 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic inline void mv_cesa_skcipher_prepare(struct crypto_async_request *req, 1798c2ecf20Sopenharmony_ci struct mv_cesa_engine *engine) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci struct skcipher_request *skreq = skcipher_request_cast(req); 1828c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(skreq); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci creq->base.engine = engine; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) 1878c2ecf20Sopenharmony_ci mv_cesa_skcipher_dma_prepare(skreq); 1888c2ecf20Sopenharmony_ci else 1898c2ecf20Sopenharmony_ci mv_cesa_skcipher_std_prepare(skreq); 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic inline void 1938c2ecf20Sopenharmony_cimv_cesa_skcipher_req_cleanup(struct crypto_async_request *req) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct skcipher_request *skreq = skcipher_request_cast(req); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci mv_cesa_skcipher_cleanup(skreq); 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic void 2018c2ecf20Sopenharmony_cimv_cesa_skcipher_complete(struct crypto_async_request *req) 2028c2ecf20Sopenharmony_ci{ 2038c2ecf20Sopenharmony_ci struct skcipher_request *skreq = skcipher_request_cast(req); 2048c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(skreq); 2058c2ecf20Sopenharmony_ci struct mv_cesa_engine *engine = creq->base.engine; 2068c2ecf20Sopenharmony_ci unsigned int ivsize; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci atomic_sub(skreq->cryptlen, &engine->load); 2098c2ecf20Sopenharmony_ci ivsize = crypto_skcipher_ivsize(crypto_skcipher_reqtfm(skreq)); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) { 2128c2ecf20Sopenharmony_ci struct mv_cesa_req *basereq; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci basereq = &creq->base; 2158c2ecf20Sopenharmony_ci memcpy(skreq->iv, basereq->chain.last->op->ctx.skcipher.iv, 2168c2ecf20Sopenharmony_ci ivsize); 2178c2ecf20Sopenharmony_ci } else { 2188c2ecf20Sopenharmony_ci memcpy_fromio(skreq->iv, 2198c2ecf20Sopenharmony_ci engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET, 2208c2ecf20Sopenharmony_ci ivsize); 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cistatic const struct mv_cesa_req_ops mv_cesa_skcipher_req_ops = { 2258c2ecf20Sopenharmony_ci .step = mv_cesa_skcipher_step, 2268c2ecf20Sopenharmony_ci .process = mv_cesa_skcipher_process, 2278c2ecf20Sopenharmony_ci .cleanup = mv_cesa_skcipher_req_cleanup, 2288c2ecf20Sopenharmony_ci .complete = mv_cesa_skcipher_complete, 2298c2ecf20Sopenharmony_ci}; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic void mv_cesa_skcipher_cra_exit(struct crypto_tfm *tfm) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci void *ctx = crypto_tfm_ctx(tfm); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci memzero_explicit(ctx, tfm->__crt_alg->cra_ctxsize); 2368c2ecf20Sopenharmony_ci} 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cistatic int mv_cesa_skcipher_cra_init(struct crypto_tfm *tfm) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci struct mv_cesa_ctx *ctx = crypto_tfm_ctx(tfm); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci ctx->ops = &mv_cesa_skcipher_req_ops; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 2458c2ecf20Sopenharmony_ci sizeof(struct mv_cesa_skcipher_req)); 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci return 0; 2488c2ecf20Sopenharmony_ci} 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_cistatic int mv_cesa_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 2518c2ecf20Sopenharmony_ci unsigned int len) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 2548c2ecf20Sopenharmony_ci struct mv_cesa_aes_ctx *ctx = crypto_tfm_ctx(tfm); 2558c2ecf20Sopenharmony_ci int remaining; 2568c2ecf20Sopenharmony_ci int offset; 2578c2ecf20Sopenharmony_ci int ret; 2588c2ecf20Sopenharmony_ci int i; 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci ret = aes_expandkey(&ctx->aes, key, len); 2618c2ecf20Sopenharmony_ci if (ret) 2628c2ecf20Sopenharmony_ci return ret; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci remaining = (ctx->aes.key_length - 16) / 4; 2658c2ecf20Sopenharmony_ci offset = ctx->aes.key_length + 24 - remaining; 2668c2ecf20Sopenharmony_ci for (i = 0; i < remaining; i++) 2678c2ecf20Sopenharmony_ci ctx->aes.key_dec[4 + i] = ctx->aes.key_enc[offset + i]; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci return 0; 2708c2ecf20Sopenharmony_ci} 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cistatic int mv_cesa_des_setkey(struct crypto_skcipher *cipher, const u8 *key, 2738c2ecf20Sopenharmony_ci unsigned int len) 2748c2ecf20Sopenharmony_ci{ 2758c2ecf20Sopenharmony_ci struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher); 2768c2ecf20Sopenharmony_ci int err; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci err = verify_skcipher_des_key(cipher, key); 2798c2ecf20Sopenharmony_ci if (err) 2808c2ecf20Sopenharmony_ci return err; 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci memcpy(ctx->key, key, DES_KEY_SIZE); 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci return 0; 2858c2ecf20Sopenharmony_ci} 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_cistatic int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher, 2888c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 2898c2ecf20Sopenharmony_ci{ 2908c2ecf20Sopenharmony_ci struct mv_cesa_des3_ctx *ctx = crypto_skcipher_ctx(cipher); 2918c2ecf20Sopenharmony_ci int err; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci err = verify_skcipher_des3_key(cipher, key); 2948c2ecf20Sopenharmony_ci if (err) 2958c2ecf20Sopenharmony_ci return err; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci memcpy(ctx->key, key, DES3_EDE_KEY_SIZE); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci return 0; 3008c2ecf20Sopenharmony_ci} 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cistatic int mv_cesa_skcipher_dma_req_init(struct skcipher_request *req, 3038c2ecf20Sopenharmony_ci const struct mv_cesa_op_ctx *op_templ) 3048c2ecf20Sopenharmony_ci{ 3058c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 3068c2ecf20Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 3078c2ecf20Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 3088c2ecf20Sopenharmony_ci struct mv_cesa_req *basereq = &creq->base; 3098c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_dma_iter iter; 3108c2ecf20Sopenharmony_ci bool skip_ctx = false; 3118c2ecf20Sopenharmony_ci int ret; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci basereq->chain.first = NULL; 3148c2ecf20Sopenharmony_ci basereq->chain.last = NULL; 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci if (req->src != req->dst) { 3178c2ecf20Sopenharmony_ci ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents, 3188c2ecf20Sopenharmony_ci DMA_TO_DEVICE); 3198c2ecf20Sopenharmony_ci if (!ret) 3208c2ecf20Sopenharmony_ci return -ENOMEM; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci ret = dma_map_sg(cesa_dev->dev, req->dst, creq->dst_nents, 3238c2ecf20Sopenharmony_ci DMA_FROM_DEVICE); 3248c2ecf20Sopenharmony_ci if (!ret) { 3258c2ecf20Sopenharmony_ci ret = -ENOMEM; 3268c2ecf20Sopenharmony_ci goto err_unmap_src; 3278c2ecf20Sopenharmony_ci } 3288c2ecf20Sopenharmony_ci } else { 3298c2ecf20Sopenharmony_ci ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents, 3308c2ecf20Sopenharmony_ci DMA_BIDIRECTIONAL); 3318c2ecf20Sopenharmony_ci if (!ret) 3328c2ecf20Sopenharmony_ci return -ENOMEM; 3338c2ecf20Sopenharmony_ci } 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci mv_cesa_tdma_desc_iter_init(&basereq->chain); 3368c2ecf20Sopenharmony_ci mv_cesa_skcipher_req_iter_init(&iter, req); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci do { 3398c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *op; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci op = mv_cesa_dma_add_op(&basereq->chain, op_templ, skip_ctx, 3428c2ecf20Sopenharmony_ci flags); 3438c2ecf20Sopenharmony_ci if (IS_ERR(op)) { 3448c2ecf20Sopenharmony_ci ret = PTR_ERR(op); 3458c2ecf20Sopenharmony_ci goto err_free_tdma; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci skip_ctx = true; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci mv_cesa_set_crypt_op_len(op, iter.base.op_len); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci /* Add input transfers */ 3528c2ecf20Sopenharmony_ci ret = mv_cesa_dma_add_op_transfers(&basereq->chain, &iter.base, 3538c2ecf20Sopenharmony_ci &iter.src, flags); 3548c2ecf20Sopenharmony_ci if (ret) 3558c2ecf20Sopenharmony_ci goto err_free_tdma; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci /* Add dummy desc to launch the crypto operation */ 3588c2ecf20Sopenharmony_ci ret = mv_cesa_dma_add_dummy_launch(&basereq->chain, flags); 3598c2ecf20Sopenharmony_ci if (ret) 3608c2ecf20Sopenharmony_ci goto err_free_tdma; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci /* Add output transfers */ 3638c2ecf20Sopenharmony_ci ret = mv_cesa_dma_add_op_transfers(&basereq->chain, &iter.base, 3648c2ecf20Sopenharmony_ci &iter.dst, flags); 3658c2ecf20Sopenharmony_ci if (ret) 3668c2ecf20Sopenharmony_ci goto err_free_tdma; 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci } while (mv_cesa_skcipher_req_iter_next_op(&iter)); 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci /* Add output data for IV */ 3718c2ecf20Sopenharmony_ci ret = mv_cesa_dma_add_result_op(&basereq->chain, 3728c2ecf20Sopenharmony_ci CESA_SA_CFG_SRAM_OFFSET, 3738c2ecf20Sopenharmony_ci CESA_SA_DATA_SRAM_OFFSET, 3748c2ecf20Sopenharmony_ci CESA_TDMA_SRC_IN_SRAM, flags); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci if (ret) 3778c2ecf20Sopenharmony_ci goto err_free_tdma; 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci basereq->chain.last->flags |= CESA_TDMA_END_OF_REQ; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci return 0; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_cierr_free_tdma: 3848c2ecf20Sopenharmony_ci mv_cesa_dma_cleanup(basereq); 3858c2ecf20Sopenharmony_ci if (req->dst != req->src) 3868c2ecf20Sopenharmony_ci dma_unmap_sg(cesa_dev->dev, req->dst, creq->dst_nents, 3878c2ecf20Sopenharmony_ci DMA_FROM_DEVICE); 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_cierr_unmap_src: 3908c2ecf20Sopenharmony_ci dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, 3918c2ecf20Sopenharmony_ci req->dst != req->src ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL); 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci return ret; 3948c2ecf20Sopenharmony_ci} 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_cistatic inline int 3978c2ecf20Sopenharmony_cimv_cesa_skcipher_std_req_init(struct skcipher_request *req, 3988c2ecf20Sopenharmony_ci const struct mv_cesa_op_ctx *op_templ) 3998c2ecf20Sopenharmony_ci{ 4008c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 4018c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_std_req *sreq = &creq->std; 4028c2ecf20Sopenharmony_ci struct mv_cesa_req *basereq = &creq->base; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci sreq->op = *op_templ; 4058c2ecf20Sopenharmony_ci sreq->skip_ctx = false; 4068c2ecf20Sopenharmony_ci basereq->chain.first = NULL; 4078c2ecf20Sopenharmony_ci basereq->chain.last = NULL; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci return 0; 4108c2ecf20Sopenharmony_ci} 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_cistatic int mv_cesa_skcipher_req_init(struct skcipher_request *req, 4138c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *tmpl) 4148c2ecf20Sopenharmony_ci{ 4158c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 4168c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 4178c2ecf20Sopenharmony_ci unsigned int blksize = crypto_skcipher_blocksize(tfm); 4188c2ecf20Sopenharmony_ci int ret; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci if (!IS_ALIGNED(req->cryptlen, blksize)) 4218c2ecf20Sopenharmony_ci return -EINVAL; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci creq->src_nents = sg_nents_for_len(req->src, req->cryptlen); 4248c2ecf20Sopenharmony_ci if (creq->src_nents < 0) { 4258c2ecf20Sopenharmony_ci dev_err(cesa_dev->dev, "Invalid number of src SG"); 4268c2ecf20Sopenharmony_ci return creq->src_nents; 4278c2ecf20Sopenharmony_ci } 4288c2ecf20Sopenharmony_ci creq->dst_nents = sg_nents_for_len(req->dst, req->cryptlen); 4298c2ecf20Sopenharmony_ci if (creq->dst_nents < 0) { 4308c2ecf20Sopenharmony_ci dev_err(cesa_dev->dev, "Invalid number of dst SG"); 4318c2ecf20Sopenharmony_ci return creq->dst_nents; 4328c2ecf20Sopenharmony_ci } 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_OP_CRYPT_ONLY, 4358c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_OP_MSK); 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci if (cesa_dev->caps->has_tdma) 4388c2ecf20Sopenharmony_ci ret = mv_cesa_skcipher_dma_req_init(req, tmpl); 4398c2ecf20Sopenharmony_ci else 4408c2ecf20Sopenharmony_ci ret = mv_cesa_skcipher_std_req_init(req, tmpl); 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci return ret; 4438c2ecf20Sopenharmony_ci} 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_cistatic int mv_cesa_skcipher_queue_req(struct skcipher_request *req, 4468c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *tmpl) 4478c2ecf20Sopenharmony_ci{ 4488c2ecf20Sopenharmony_ci int ret; 4498c2ecf20Sopenharmony_ci struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); 4508c2ecf20Sopenharmony_ci struct mv_cesa_engine *engine; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci ret = mv_cesa_skcipher_req_init(req, tmpl); 4538c2ecf20Sopenharmony_ci if (ret) 4548c2ecf20Sopenharmony_ci return ret; 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci engine = mv_cesa_select_engine(req->cryptlen); 4578c2ecf20Sopenharmony_ci mv_cesa_skcipher_prepare(&req->base, engine); 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci ret = mv_cesa_queue_req(&req->base, &creq->base); 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci if (mv_cesa_req_needs_cleanup(&req->base, ret)) 4628c2ecf20Sopenharmony_ci mv_cesa_skcipher_cleanup(req); 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci return ret; 4658c2ecf20Sopenharmony_ci} 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_cistatic int mv_cesa_des_op(struct skcipher_request *req, 4688c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *tmpl) 4698c2ecf20Sopenharmony_ci{ 4708c2ecf20Sopenharmony_ci struct mv_cesa_des_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTM_DES, 4738c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTM_MSK); 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci memcpy(tmpl->ctx.skcipher.key, ctx->key, DES_KEY_SIZE); 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci return mv_cesa_skcipher_queue_req(req, tmpl); 4788c2ecf20Sopenharmony_ci} 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_cistatic int mv_cesa_ecb_des_encrypt(struct skcipher_request *req) 4818c2ecf20Sopenharmony_ci{ 4828c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, 4858c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_ECB | 4868c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_DIR_ENC); 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci return mv_cesa_des_op(req, &tmpl); 4898c2ecf20Sopenharmony_ci} 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_cistatic int mv_cesa_ecb_des_decrypt(struct skcipher_request *req) 4928c2ecf20Sopenharmony_ci{ 4938c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, 4968c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_ECB | 4978c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_DIR_DEC); 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci return mv_cesa_des_op(req, &tmpl); 5008c2ecf20Sopenharmony_ci} 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_cistruct skcipher_alg mv_cesa_ecb_des_alg = { 5038c2ecf20Sopenharmony_ci .setkey = mv_cesa_des_setkey, 5048c2ecf20Sopenharmony_ci .encrypt = mv_cesa_ecb_des_encrypt, 5058c2ecf20Sopenharmony_ci .decrypt = mv_cesa_ecb_des_decrypt, 5068c2ecf20Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 5078c2ecf20Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 5088c2ecf20Sopenharmony_ci .base = { 5098c2ecf20Sopenharmony_ci .cra_name = "ecb(des)", 5108c2ecf20Sopenharmony_ci .cra_driver_name = "mv-ecb-des", 5118c2ecf20Sopenharmony_ci .cra_priority = 300, 5128c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 5138c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 5148c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 5158c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct mv_cesa_des_ctx), 5168c2ecf20Sopenharmony_ci .cra_alignmask = 0, 5178c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 5188c2ecf20Sopenharmony_ci .cra_init = mv_cesa_skcipher_cra_init, 5198c2ecf20Sopenharmony_ci .cra_exit = mv_cesa_skcipher_cra_exit, 5208c2ecf20Sopenharmony_ci }, 5218c2ecf20Sopenharmony_ci}; 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_des_op(struct skcipher_request *req, 5248c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *tmpl) 5258c2ecf20Sopenharmony_ci{ 5268c2ecf20Sopenharmony_ci mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTCM_CBC, 5278c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_MSK); 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci memcpy(tmpl->ctx.skcipher.iv, req->iv, DES_BLOCK_SIZE); 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci return mv_cesa_des_op(req, tmpl); 5328c2ecf20Sopenharmony_ci} 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_des_encrypt(struct skcipher_request *req) 5358c2ecf20Sopenharmony_ci{ 5368c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_DIR_ENC); 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci return mv_cesa_cbc_des_op(req, &tmpl); 5418c2ecf20Sopenharmony_ci} 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_des_decrypt(struct skcipher_request *req) 5448c2ecf20Sopenharmony_ci{ 5458c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_DIR_DEC); 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci return mv_cesa_cbc_des_op(req, &tmpl); 5508c2ecf20Sopenharmony_ci} 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_cistruct skcipher_alg mv_cesa_cbc_des_alg = { 5538c2ecf20Sopenharmony_ci .setkey = mv_cesa_des_setkey, 5548c2ecf20Sopenharmony_ci .encrypt = mv_cesa_cbc_des_encrypt, 5558c2ecf20Sopenharmony_ci .decrypt = mv_cesa_cbc_des_decrypt, 5568c2ecf20Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 5578c2ecf20Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 5588c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 5598c2ecf20Sopenharmony_ci .base = { 5608c2ecf20Sopenharmony_ci .cra_name = "cbc(des)", 5618c2ecf20Sopenharmony_ci .cra_driver_name = "mv-cbc-des", 5628c2ecf20Sopenharmony_ci .cra_priority = 300, 5638c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 5648c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 5658c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 5668c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct mv_cesa_des_ctx), 5678c2ecf20Sopenharmony_ci .cra_alignmask = 0, 5688c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 5698c2ecf20Sopenharmony_ci .cra_init = mv_cesa_skcipher_cra_init, 5708c2ecf20Sopenharmony_ci .cra_exit = mv_cesa_skcipher_cra_exit, 5718c2ecf20Sopenharmony_ci }, 5728c2ecf20Sopenharmony_ci}; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_cistatic int mv_cesa_des3_op(struct skcipher_request *req, 5758c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *tmpl) 5768c2ecf20Sopenharmony_ci{ 5778c2ecf20Sopenharmony_ci struct mv_cesa_des3_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTM_3DES, 5808c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTM_MSK); 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci memcpy(tmpl->ctx.skcipher.key, ctx->key, DES3_EDE_KEY_SIZE); 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci return mv_cesa_skcipher_queue_req(req, tmpl); 5858c2ecf20Sopenharmony_ci} 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_cistatic int mv_cesa_ecb_des3_ede_encrypt(struct skcipher_request *req) 5888c2ecf20Sopenharmony_ci{ 5898c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, 5928c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_ECB | 5938c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_3DES_EDE | 5948c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_DIR_ENC); 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci return mv_cesa_des3_op(req, &tmpl); 5978c2ecf20Sopenharmony_ci} 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_cistatic int mv_cesa_ecb_des3_ede_decrypt(struct skcipher_request *req) 6008c2ecf20Sopenharmony_ci{ 6018c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, 6048c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_ECB | 6058c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_3DES_EDE | 6068c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_DIR_DEC); 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci return mv_cesa_des3_op(req, &tmpl); 6098c2ecf20Sopenharmony_ci} 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_cistruct skcipher_alg mv_cesa_ecb_des3_ede_alg = { 6128c2ecf20Sopenharmony_ci .setkey = mv_cesa_des3_ede_setkey, 6138c2ecf20Sopenharmony_ci .encrypt = mv_cesa_ecb_des3_ede_encrypt, 6148c2ecf20Sopenharmony_ci .decrypt = mv_cesa_ecb_des3_ede_decrypt, 6158c2ecf20Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 6168c2ecf20Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 6178c2ecf20Sopenharmony_ci .base = { 6188c2ecf20Sopenharmony_ci .cra_name = "ecb(des3_ede)", 6198c2ecf20Sopenharmony_ci .cra_driver_name = "mv-ecb-des3-ede", 6208c2ecf20Sopenharmony_ci .cra_priority = 300, 6218c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 6228c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 6238c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 6248c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct mv_cesa_des3_ctx), 6258c2ecf20Sopenharmony_ci .cra_alignmask = 0, 6268c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 6278c2ecf20Sopenharmony_ci .cra_init = mv_cesa_skcipher_cra_init, 6288c2ecf20Sopenharmony_ci .cra_exit = mv_cesa_skcipher_cra_exit, 6298c2ecf20Sopenharmony_ci }, 6308c2ecf20Sopenharmony_ci}; 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_des3_op(struct skcipher_request *req, 6338c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *tmpl) 6348c2ecf20Sopenharmony_ci{ 6358c2ecf20Sopenharmony_ci memcpy(tmpl->ctx.skcipher.iv, req->iv, DES3_EDE_BLOCK_SIZE); 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci return mv_cesa_des3_op(req, tmpl); 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_des3_ede_encrypt(struct skcipher_request *req) 6418c2ecf20Sopenharmony_ci{ 6428c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, 6458c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_CBC | 6468c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_3DES_EDE | 6478c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_DIR_ENC); 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci return mv_cesa_cbc_des3_op(req, &tmpl); 6508c2ecf20Sopenharmony_ci} 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_des3_ede_decrypt(struct skcipher_request *req) 6538c2ecf20Sopenharmony_ci{ 6548c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, 6578c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_CBC | 6588c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_3DES_EDE | 6598c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_DIR_DEC); 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_ci return mv_cesa_cbc_des3_op(req, &tmpl); 6628c2ecf20Sopenharmony_ci} 6638c2ecf20Sopenharmony_ci 6648c2ecf20Sopenharmony_cistruct skcipher_alg mv_cesa_cbc_des3_ede_alg = { 6658c2ecf20Sopenharmony_ci .setkey = mv_cesa_des3_ede_setkey, 6668c2ecf20Sopenharmony_ci .encrypt = mv_cesa_cbc_des3_ede_encrypt, 6678c2ecf20Sopenharmony_ci .decrypt = mv_cesa_cbc_des3_ede_decrypt, 6688c2ecf20Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 6698c2ecf20Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 6708c2ecf20Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 6718c2ecf20Sopenharmony_ci .base = { 6728c2ecf20Sopenharmony_ci .cra_name = "cbc(des3_ede)", 6738c2ecf20Sopenharmony_ci .cra_driver_name = "mv-cbc-des3-ede", 6748c2ecf20Sopenharmony_ci .cra_priority = 300, 6758c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 6768c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 6778c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 6788c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct mv_cesa_des3_ctx), 6798c2ecf20Sopenharmony_ci .cra_alignmask = 0, 6808c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 6818c2ecf20Sopenharmony_ci .cra_init = mv_cesa_skcipher_cra_init, 6828c2ecf20Sopenharmony_ci .cra_exit = mv_cesa_skcipher_cra_exit, 6838c2ecf20Sopenharmony_ci }, 6848c2ecf20Sopenharmony_ci}; 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_cistatic int mv_cesa_aes_op(struct skcipher_request *req, 6878c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *tmpl) 6888c2ecf20Sopenharmony_ci{ 6898c2ecf20Sopenharmony_ci struct mv_cesa_aes_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 6908c2ecf20Sopenharmony_ci int i; 6918c2ecf20Sopenharmony_ci u32 *key; 6928c2ecf20Sopenharmony_ci u32 cfg; 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci cfg = CESA_SA_DESC_CFG_CRYPTM_AES; 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci if (mv_cesa_get_op_cfg(tmpl) & CESA_SA_DESC_CFG_DIR_DEC) 6978c2ecf20Sopenharmony_ci key = ctx->aes.key_dec; 6988c2ecf20Sopenharmony_ci else 6998c2ecf20Sopenharmony_ci key = ctx->aes.key_enc; 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci for (i = 0; i < ctx->aes.key_length / sizeof(u32); i++) 7028c2ecf20Sopenharmony_ci tmpl->ctx.skcipher.key[i] = cpu_to_le32(key[i]); 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci if (ctx->aes.key_length == 24) 7058c2ecf20Sopenharmony_ci cfg |= CESA_SA_DESC_CFG_AES_LEN_192; 7068c2ecf20Sopenharmony_ci else if (ctx->aes.key_length == 32) 7078c2ecf20Sopenharmony_ci cfg |= CESA_SA_DESC_CFG_AES_LEN_256; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci mv_cesa_update_op_cfg(tmpl, cfg, 7108c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTM_MSK | 7118c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_AES_LEN_MSK); 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci return mv_cesa_skcipher_queue_req(req, tmpl); 7148c2ecf20Sopenharmony_ci} 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_cistatic int mv_cesa_ecb_aes_encrypt(struct skcipher_request *req) 7178c2ecf20Sopenharmony_ci{ 7188c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, 7218c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_ECB | 7228c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_DIR_ENC); 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci return mv_cesa_aes_op(req, &tmpl); 7258c2ecf20Sopenharmony_ci} 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_cistatic int mv_cesa_ecb_aes_decrypt(struct skcipher_request *req) 7288c2ecf20Sopenharmony_ci{ 7298c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, 7328c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_ECB | 7338c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_DIR_DEC); 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci return mv_cesa_aes_op(req, &tmpl); 7368c2ecf20Sopenharmony_ci} 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_cistruct skcipher_alg mv_cesa_ecb_aes_alg = { 7398c2ecf20Sopenharmony_ci .setkey = mv_cesa_aes_setkey, 7408c2ecf20Sopenharmony_ci .encrypt = mv_cesa_ecb_aes_encrypt, 7418c2ecf20Sopenharmony_ci .decrypt = mv_cesa_ecb_aes_decrypt, 7428c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 7438c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 7448c2ecf20Sopenharmony_ci .base = { 7458c2ecf20Sopenharmony_ci .cra_name = "ecb(aes)", 7468c2ecf20Sopenharmony_ci .cra_driver_name = "mv-ecb-aes", 7478c2ecf20Sopenharmony_ci .cra_priority = 300, 7488c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 7498c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 7508c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 7518c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct mv_cesa_aes_ctx), 7528c2ecf20Sopenharmony_ci .cra_alignmask = 0, 7538c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 7548c2ecf20Sopenharmony_ci .cra_init = mv_cesa_skcipher_cra_init, 7558c2ecf20Sopenharmony_ci .cra_exit = mv_cesa_skcipher_cra_exit, 7568c2ecf20Sopenharmony_ci }, 7578c2ecf20Sopenharmony_ci}; 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_aes_op(struct skcipher_request *req, 7608c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx *tmpl) 7618c2ecf20Sopenharmony_ci{ 7628c2ecf20Sopenharmony_ci mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTCM_CBC, 7638c2ecf20Sopenharmony_ci CESA_SA_DESC_CFG_CRYPTCM_MSK); 7648c2ecf20Sopenharmony_ci memcpy(tmpl->ctx.skcipher.iv, req->iv, AES_BLOCK_SIZE); 7658c2ecf20Sopenharmony_ci 7668c2ecf20Sopenharmony_ci return mv_cesa_aes_op(req, tmpl); 7678c2ecf20Sopenharmony_ci} 7688c2ecf20Sopenharmony_ci 7698c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_aes_encrypt(struct skcipher_request *req) 7708c2ecf20Sopenharmony_ci{ 7718c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_DIR_ENC); 7748c2ecf20Sopenharmony_ci 7758c2ecf20Sopenharmony_ci return mv_cesa_cbc_aes_op(req, &tmpl); 7768c2ecf20Sopenharmony_ci} 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_cistatic int mv_cesa_cbc_aes_decrypt(struct skcipher_request *req) 7798c2ecf20Sopenharmony_ci{ 7808c2ecf20Sopenharmony_ci struct mv_cesa_op_ctx tmpl; 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_DIR_DEC); 7838c2ecf20Sopenharmony_ci 7848c2ecf20Sopenharmony_ci return mv_cesa_cbc_aes_op(req, &tmpl); 7858c2ecf20Sopenharmony_ci} 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_cistruct skcipher_alg mv_cesa_cbc_aes_alg = { 7888c2ecf20Sopenharmony_ci .setkey = mv_cesa_aes_setkey, 7898c2ecf20Sopenharmony_ci .encrypt = mv_cesa_cbc_aes_encrypt, 7908c2ecf20Sopenharmony_ci .decrypt = mv_cesa_cbc_aes_decrypt, 7918c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 7928c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 7938c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 7948c2ecf20Sopenharmony_ci .base = { 7958c2ecf20Sopenharmony_ci .cra_name = "cbc(aes)", 7968c2ecf20Sopenharmony_ci .cra_driver_name = "mv-cbc-aes", 7978c2ecf20Sopenharmony_ci .cra_priority = 300, 7988c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | 7998c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 8008c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 8018c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct mv_cesa_aes_ctx), 8028c2ecf20Sopenharmony_ci .cra_alignmask = 0, 8038c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 8048c2ecf20Sopenharmony_ci .cra_init = mv_cesa_skcipher_cra_init, 8058c2ecf20Sopenharmony_ci .cra_exit = mv_cesa_skcipher_cra_exit, 8068c2ecf20Sopenharmony_ci }, 8078c2ecf20Sopenharmony_ci}; 808