1618b5dc4SHoria Geantă // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 28c419778STudor Ambarus /* 38c419778STudor Ambarus * caam - Freescale FSL CAAM support for Public Key Cryptography 48c419778STudor Ambarus * 58c419778STudor Ambarus * Copyright 2016 Freescale Semiconductor, Inc. 6a5e5c133SHoria Geantă * Copyright 2018-2019 NXP 78c419778STudor Ambarus * 88c419778STudor Ambarus * There is no Shared Descriptor for PKC so that the Job Descriptor must carry 98c419778STudor Ambarus * all the desired key parameters, input and output pointers. 108c419778STudor Ambarus */ 118c419778STudor Ambarus #include "compat.h" 128c419778STudor Ambarus #include "regs.h" 138c419778STudor Ambarus #include "intern.h" 148c419778STudor Ambarus #include "jr.h" 158c419778STudor Ambarus #include "error.h" 168c419778STudor Ambarus #include "desc_constr.h" 178c419778STudor Ambarus #include "sg_sw_sec4.h" 188c419778STudor Ambarus #include "caampkc.h" 198c419778STudor Ambarus 208c419778STudor Ambarus #define DESC_RSA_PUB_LEN (2 * CAAM_CMD_SZ + sizeof(struct rsa_pub_pdb)) 218c419778STudor Ambarus #define DESC_RSA_PRIV_F1_LEN (2 * CAAM_CMD_SZ + \ 228c419778STudor Ambarus sizeof(struct rsa_priv_f1_pdb)) 2352e26d77SRadu Alexe #define DESC_RSA_PRIV_F2_LEN (2 * CAAM_CMD_SZ + \ 2452e26d77SRadu Alexe sizeof(struct rsa_priv_f2_pdb)) 254a651b12SRadu Alexe #define DESC_RSA_PRIV_F3_LEN (2 * CAAM_CMD_SZ + \ 264a651b12SRadu Alexe sizeof(struct rsa_priv_f3_pdb)) 27c3725f7cSIuliana Prodan #define CAAM_RSA_MAX_INPUT_SIZE 512 /* for a 4096-bit modulus */ 28c3725f7cSIuliana Prodan 29c3725f7cSIuliana Prodan /* buffer filled with zeros, used for padding */ 30c3725f7cSIuliana Prodan static u8 *zero_buffer; 318c419778STudor Ambarus 328c419778STudor Ambarus static void rsa_io_unmap(struct device *dev, struct rsa_edesc *edesc, 338c419778STudor Ambarus struct akcipher_request *req) 348c419778STudor Ambarus { 353b2614cbSIuliana Prodan struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); 363b2614cbSIuliana Prodan 378c419778STudor Ambarus dma_unmap_sg(dev, req->dst, edesc->dst_nents, DMA_FROM_DEVICE); 383b2614cbSIuliana Prodan dma_unmap_sg(dev, req_ctx->fixup_src, edesc->src_nents, DMA_TO_DEVICE); 398c419778STudor Ambarus 408c419778STudor Ambarus if (edesc->sec4_sg_bytes) 418c419778STudor Ambarus dma_unmap_single(dev, edesc->sec4_sg_dma, edesc->sec4_sg_bytes, 428c419778STudor Ambarus DMA_TO_DEVICE); 438c419778STudor Ambarus } 448c419778STudor Ambarus 458c419778STudor Ambarus static void rsa_pub_unmap(struct device *dev, struct rsa_edesc *edesc, 468c419778STudor Ambarus struct akcipher_request *req) 478c419778STudor Ambarus { 488c419778STudor Ambarus struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 498c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 508c419778STudor Ambarus struct caam_rsa_key *key = &ctx->key; 518c419778STudor Ambarus struct rsa_pub_pdb *pdb = &edesc->pdb.pub; 528c419778STudor Ambarus 538c419778STudor Ambarus dma_unmap_single(dev, pdb->n_dma, key->n_sz, DMA_TO_DEVICE); 548c419778STudor Ambarus dma_unmap_single(dev, pdb->e_dma, key->e_sz, DMA_TO_DEVICE); 558c419778STudor Ambarus } 568c419778STudor Ambarus 578c419778STudor Ambarus static void rsa_priv_f1_unmap(struct device *dev, struct rsa_edesc *edesc, 588c419778STudor Ambarus struct akcipher_request *req) 598c419778STudor Ambarus { 608c419778STudor Ambarus struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 618c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 628c419778STudor Ambarus struct caam_rsa_key *key = &ctx->key; 638c419778STudor Ambarus struct rsa_priv_f1_pdb *pdb = &edesc->pdb.priv_f1; 648c419778STudor Ambarus 658c419778STudor Ambarus dma_unmap_single(dev, pdb->n_dma, key->n_sz, DMA_TO_DEVICE); 668c419778STudor Ambarus dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE); 678c419778STudor Ambarus } 688c419778STudor Ambarus 6952e26d77SRadu Alexe static void rsa_priv_f2_unmap(struct device *dev, struct rsa_edesc *edesc, 7052e26d77SRadu Alexe struct akcipher_request *req) 7152e26d77SRadu Alexe { 7252e26d77SRadu Alexe struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 7352e26d77SRadu Alexe struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 7452e26d77SRadu Alexe struct caam_rsa_key *key = &ctx->key; 7552e26d77SRadu Alexe struct rsa_priv_f2_pdb *pdb = &edesc->pdb.priv_f2; 7652e26d77SRadu Alexe size_t p_sz = key->p_sz; 774bffaab3SHoria Geantă size_t q_sz = key->q_sz; 7852e26d77SRadu Alexe 7952e26d77SRadu Alexe dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE); 8052e26d77SRadu Alexe dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE); 8152e26d77SRadu Alexe dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE); 82f1bf9e60SHoria Geantă dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL); 83f1bf9e60SHoria Geantă dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL); 8452e26d77SRadu Alexe } 8552e26d77SRadu Alexe 864a651b12SRadu Alexe static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc, 874a651b12SRadu Alexe struct akcipher_request *req) 884a651b12SRadu Alexe { 894a651b12SRadu Alexe struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 904a651b12SRadu Alexe struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 914a651b12SRadu Alexe struct caam_rsa_key *key = &ctx->key; 924a651b12SRadu Alexe struct rsa_priv_f3_pdb *pdb = &edesc->pdb.priv_f3; 934a651b12SRadu Alexe size_t p_sz = key->p_sz; 944bffaab3SHoria Geantă size_t q_sz = key->q_sz; 954a651b12SRadu Alexe 964a651b12SRadu Alexe dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE); 974a651b12SRadu Alexe dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE); 984a651b12SRadu Alexe dma_unmap_single(dev, pdb->dp_dma, p_sz, DMA_TO_DEVICE); 994a651b12SRadu Alexe dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE); 1004a651b12SRadu Alexe dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE); 101f1bf9e60SHoria Geantă dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL); 102f1bf9e60SHoria Geantă dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL); 1034a651b12SRadu Alexe } 1044a651b12SRadu Alexe 1058c419778STudor Ambarus /* RSA Job Completion handler */ 1068c419778STudor Ambarus static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context) 1078c419778STudor Ambarus { 1088c419778STudor Ambarus struct akcipher_request *req = context; 1098c419778STudor Ambarus struct rsa_edesc *edesc; 110*1984aaeeSHoria Geantă int ecode = 0; 1118c419778STudor Ambarus 1128c419778STudor Ambarus if (err) 113*1984aaeeSHoria Geantă ecode = caam_jr_strstatus(dev, err); 1148c419778STudor Ambarus 1158c419778STudor Ambarus edesc = container_of(desc, struct rsa_edesc, hw_desc[0]); 1168c419778STudor Ambarus 1178c419778STudor Ambarus rsa_pub_unmap(dev, edesc, req); 1188c419778STudor Ambarus rsa_io_unmap(dev, edesc, req); 1198c419778STudor Ambarus kfree(edesc); 1208c419778STudor Ambarus 121*1984aaeeSHoria Geantă akcipher_request_complete(req, ecode); 1228c419778STudor Ambarus } 1238c419778STudor Ambarus 1248c419778STudor Ambarus static void rsa_priv_f1_done(struct device *dev, u32 *desc, u32 err, 1258c419778STudor Ambarus void *context) 1268c419778STudor Ambarus { 1278c419778STudor Ambarus struct akcipher_request *req = context; 1288c419778STudor Ambarus struct rsa_edesc *edesc; 129*1984aaeeSHoria Geantă int ecode = 0; 1308c419778STudor Ambarus 1318c419778STudor Ambarus if (err) 132*1984aaeeSHoria Geantă ecode = caam_jr_strstatus(dev, err); 1338c419778STudor Ambarus 1348c419778STudor Ambarus edesc = container_of(desc, struct rsa_edesc, hw_desc[0]); 1358c419778STudor Ambarus 1368c419778STudor Ambarus rsa_priv_f1_unmap(dev, edesc, req); 1378c419778STudor Ambarus rsa_io_unmap(dev, edesc, req); 1388c419778STudor Ambarus kfree(edesc); 1398c419778STudor Ambarus 140*1984aaeeSHoria Geantă akcipher_request_complete(req, ecode); 1418c419778STudor Ambarus } 1428c419778STudor Ambarus 14352e26d77SRadu Alexe static void rsa_priv_f2_done(struct device *dev, u32 *desc, u32 err, 14452e26d77SRadu Alexe void *context) 14552e26d77SRadu Alexe { 14652e26d77SRadu Alexe struct akcipher_request *req = context; 14752e26d77SRadu Alexe struct rsa_edesc *edesc; 148*1984aaeeSHoria Geantă int ecode = 0; 14952e26d77SRadu Alexe 15052e26d77SRadu Alexe if (err) 151*1984aaeeSHoria Geantă ecode = caam_jr_strstatus(dev, err); 15252e26d77SRadu Alexe 15352e26d77SRadu Alexe edesc = container_of(desc, struct rsa_edesc, hw_desc[0]); 15452e26d77SRadu Alexe 15552e26d77SRadu Alexe rsa_priv_f2_unmap(dev, edesc, req); 15652e26d77SRadu Alexe rsa_io_unmap(dev, edesc, req); 15752e26d77SRadu Alexe kfree(edesc); 15852e26d77SRadu Alexe 159*1984aaeeSHoria Geantă akcipher_request_complete(req, ecode); 16052e26d77SRadu Alexe } 16152e26d77SRadu Alexe 1624a651b12SRadu Alexe static void rsa_priv_f3_done(struct device *dev, u32 *desc, u32 err, 1634a651b12SRadu Alexe void *context) 1644a651b12SRadu Alexe { 1654a651b12SRadu Alexe struct akcipher_request *req = context; 1664a651b12SRadu Alexe struct rsa_edesc *edesc; 167*1984aaeeSHoria Geantă int ecode = 0; 1684a651b12SRadu Alexe 1694a651b12SRadu Alexe if (err) 170*1984aaeeSHoria Geantă ecode = caam_jr_strstatus(dev, err); 1714a651b12SRadu Alexe 1724a651b12SRadu Alexe edesc = container_of(desc, struct rsa_edesc, hw_desc[0]); 1734a651b12SRadu Alexe 1744a651b12SRadu Alexe rsa_priv_f3_unmap(dev, edesc, req); 1754a651b12SRadu Alexe rsa_io_unmap(dev, edesc, req); 1764a651b12SRadu Alexe kfree(edesc); 1774a651b12SRadu Alexe 178*1984aaeeSHoria Geantă akcipher_request_complete(req, ecode); 1794a651b12SRadu Alexe } 1804a651b12SRadu Alexe 181c3725f7cSIuliana Prodan /** 182c3725f7cSIuliana Prodan * Count leading zeros, need it to strip, from a given scatterlist 183c3725f7cSIuliana Prodan * 184c3725f7cSIuliana Prodan * @sgl : scatterlist to count zeros from 185c3725f7cSIuliana Prodan * @nbytes: number of zeros, in bytes, to strip 186c3725f7cSIuliana Prodan * @flags : operation flags 187c3725f7cSIuliana Prodan */ 1888a2a0dd3SHoria Geantă static int caam_rsa_count_leading_zeros(struct scatterlist *sgl, 1898a2a0dd3SHoria Geantă unsigned int nbytes, 1908a2a0dd3SHoria Geantă unsigned int flags) 1918a2a0dd3SHoria Geantă { 1928a2a0dd3SHoria Geantă struct sg_mapping_iter miter; 1938a2a0dd3SHoria Geantă int lzeros, ents; 1948a2a0dd3SHoria Geantă unsigned int len; 1958a2a0dd3SHoria Geantă unsigned int tbytes = nbytes; 1968a2a0dd3SHoria Geantă const u8 *buff; 1978a2a0dd3SHoria Geantă 1988a2a0dd3SHoria Geantă ents = sg_nents_for_len(sgl, nbytes); 1998a2a0dd3SHoria Geantă if (ents < 0) 2008a2a0dd3SHoria Geantă return ents; 2018a2a0dd3SHoria Geantă 2028a2a0dd3SHoria Geantă sg_miter_start(&miter, sgl, ents, SG_MITER_FROM_SG | flags); 2038a2a0dd3SHoria Geantă 2048a2a0dd3SHoria Geantă lzeros = 0; 2058a2a0dd3SHoria Geantă len = 0; 2068a2a0dd3SHoria Geantă while (nbytes > 0) { 207c3725f7cSIuliana Prodan /* do not strip more than given bytes */ 208c3725f7cSIuliana Prodan while (len && !*buff && lzeros < nbytes) { 2098a2a0dd3SHoria Geantă lzeros++; 2108a2a0dd3SHoria Geantă len--; 2118a2a0dd3SHoria Geantă buff++; 2128a2a0dd3SHoria Geantă } 2138a2a0dd3SHoria Geantă 2148a2a0dd3SHoria Geantă if (len && *buff) 2158a2a0dd3SHoria Geantă break; 2168a2a0dd3SHoria Geantă 2178a2a0dd3SHoria Geantă sg_miter_next(&miter); 2188a2a0dd3SHoria Geantă buff = miter.addr; 2198a2a0dd3SHoria Geantă len = miter.length; 2208a2a0dd3SHoria Geantă 2218a2a0dd3SHoria Geantă nbytes -= lzeros; 2228a2a0dd3SHoria Geantă lzeros = 0; 2238a2a0dd3SHoria Geantă } 2248a2a0dd3SHoria Geantă 2258a2a0dd3SHoria Geantă miter.consumed = lzeros; 2268a2a0dd3SHoria Geantă sg_miter_stop(&miter); 2278a2a0dd3SHoria Geantă nbytes -= lzeros; 2288a2a0dd3SHoria Geantă 2298a2a0dd3SHoria Geantă return tbytes - nbytes; 2308a2a0dd3SHoria Geantă } 2318a2a0dd3SHoria Geantă 2328c419778STudor Ambarus static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req, 2338c419778STudor Ambarus size_t desclen) 2348c419778STudor Ambarus { 2358c419778STudor Ambarus struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 2368c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 2378c419778STudor Ambarus struct device *dev = ctx->dev; 2388a2a0dd3SHoria Geantă struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); 239c3725f7cSIuliana Prodan struct caam_rsa_key *key = &ctx->key; 2408c419778STudor Ambarus struct rsa_edesc *edesc; 241019d62dbSHoria Geantă gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 242019d62dbSHoria Geantă GFP_KERNEL : GFP_ATOMIC; 2438a2a0dd3SHoria Geantă int sg_flags = (flags == GFP_ATOMIC) ? SG_MITER_ATOMIC : 0; 2448c419778STudor Ambarus int sgc; 2458c419778STudor Ambarus int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; 2468c419778STudor Ambarus int src_nents, dst_nents; 247c3725f7cSIuliana Prodan unsigned int diff_size = 0; 2488a2a0dd3SHoria Geantă int lzeros; 2498a2a0dd3SHoria Geantă 250c3725f7cSIuliana Prodan if (req->src_len > key->n_sz) { 251c3725f7cSIuliana Prodan /* 252c3725f7cSIuliana Prodan * strip leading zeros and 253c3725f7cSIuliana Prodan * return the number of zeros to skip 254c3725f7cSIuliana Prodan */ 255c3725f7cSIuliana Prodan lzeros = caam_rsa_count_leading_zeros(req->src, req->src_len - 256c3725f7cSIuliana Prodan key->n_sz, sg_flags); 2578a2a0dd3SHoria Geantă if (lzeros < 0) 2588a2a0dd3SHoria Geantă return ERR_PTR(lzeros); 2598a2a0dd3SHoria Geantă 2603b2614cbSIuliana Prodan req_ctx->fixup_src = scatterwalk_ffwd(req_ctx->src, req->src, 2613b2614cbSIuliana Prodan lzeros); 2623b2614cbSIuliana Prodan req_ctx->fixup_src_len = req->src_len - lzeros; 263c3725f7cSIuliana Prodan } else { 264c3725f7cSIuliana Prodan /* 265c3725f7cSIuliana Prodan * input src is less then n key modulus, 266c3725f7cSIuliana Prodan * so there will be zero padding 267c3725f7cSIuliana Prodan */ 268c3725f7cSIuliana Prodan diff_size = key->n_sz - req->src_len; 2693b2614cbSIuliana Prodan req_ctx->fixup_src = req->src; 2703b2614cbSIuliana Prodan req_ctx->fixup_src_len = req->src_len; 271c3725f7cSIuliana Prodan } 2728c419778STudor Ambarus 2733b2614cbSIuliana Prodan src_nents = sg_nents_for_len(req_ctx->fixup_src, 2743b2614cbSIuliana Prodan req_ctx->fixup_src_len); 2758c419778STudor Ambarus dst_nents = sg_nents_for_len(req->dst, req->dst_len); 2768c419778STudor Ambarus 277c3725f7cSIuliana Prodan if (!diff_size && src_nents == 1) 278c3725f7cSIuliana Prodan sec4_sg_len = 0; /* no need for an input hw s/g table */ 279c3725f7cSIuliana Prodan else 280c3725f7cSIuliana Prodan sec4_sg_len = src_nents + !!diff_size; 281c3725f7cSIuliana Prodan sec4_sg_index = sec4_sg_len; 2828c419778STudor Ambarus if (dst_nents > 1) 283a5e5c133SHoria Geantă sec4_sg_len += pad_sg_nents(dst_nents); 284a5e5c133SHoria Geantă else 285a5e5c133SHoria Geantă sec4_sg_len = pad_sg_nents(sec4_sg_len); 2868c419778STudor Ambarus 2878c419778STudor Ambarus sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); 2888c419778STudor Ambarus 2898c419778STudor Ambarus /* allocate space for base edesc, hw desc commands and link tables */ 2908c419778STudor Ambarus edesc = kzalloc(sizeof(*edesc) + desclen + sec4_sg_bytes, 2918c419778STudor Ambarus GFP_DMA | flags); 2928c419778STudor Ambarus if (!edesc) 2938c419778STudor Ambarus return ERR_PTR(-ENOMEM); 2948c419778STudor Ambarus 2953b2614cbSIuliana Prodan sgc = dma_map_sg(dev, req_ctx->fixup_src, src_nents, DMA_TO_DEVICE); 2968c419778STudor Ambarus if (unlikely(!sgc)) { 2978c419778STudor Ambarus dev_err(dev, "unable to map source\n"); 2988c419778STudor Ambarus goto src_fail; 2998c419778STudor Ambarus } 3008c419778STudor Ambarus 3018c419778STudor Ambarus sgc = dma_map_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE); 3028c419778STudor Ambarus if (unlikely(!sgc)) { 3038c419778STudor Ambarus dev_err(dev, "unable to map destination\n"); 3048c419778STudor Ambarus goto dst_fail; 3058c419778STudor Ambarus } 3068c419778STudor Ambarus 3078c419778STudor Ambarus edesc->sec4_sg = (void *)edesc + sizeof(*edesc) + desclen; 308c3725f7cSIuliana Prodan if (diff_size) 309c3725f7cSIuliana Prodan dma_to_sec4_sg_one(edesc->sec4_sg, ctx->padding_dma, diff_size, 310c3725f7cSIuliana Prodan 0); 3118c419778STudor Ambarus 312c3725f7cSIuliana Prodan if (sec4_sg_index) 313059d73eeSHoria Geantă sg_to_sec4_sg_last(req_ctx->fixup_src, req_ctx->fixup_src_len, 3143b2614cbSIuliana Prodan edesc->sec4_sg + !!diff_size, 0); 315c3725f7cSIuliana Prodan 3168c419778STudor Ambarus if (dst_nents > 1) 317059d73eeSHoria Geantă sg_to_sec4_sg_last(req->dst, req->dst_len, 3188c419778STudor Ambarus edesc->sec4_sg + sec4_sg_index, 0); 3198c419778STudor Ambarus 3208c419778STudor Ambarus /* Save nents for later use in Job Descriptor */ 3218c419778STudor Ambarus edesc->src_nents = src_nents; 3228c419778STudor Ambarus edesc->dst_nents = dst_nents; 3238c419778STudor Ambarus 3248c419778STudor Ambarus if (!sec4_sg_bytes) 3258c419778STudor Ambarus return edesc; 3268c419778STudor Ambarus 3278c419778STudor Ambarus edesc->sec4_sg_dma = dma_map_single(dev, edesc->sec4_sg, 3288c419778STudor Ambarus sec4_sg_bytes, DMA_TO_DEVICE); 3298c419778STudor Ambarus if (dma_mapping_error(dev, edesc->sec4_sg_dma)) { 3308c419778STudor Ambarus dev_err(dev, "unable to map S/G table\n"); 3318c419778STudor Ambarus goto sec4_sg_fail; 3328c419778STudor Ambarus } 3338c419778STudor Ambarus 3348c419778STudor Ambarus edesc->sec4_sg_bytes = sec4_sg_bytes; 3358c419778STudor Ambarus 336c3725f7cSIuliana Prodan print_hex_dump_debug("caampkc sec4_sg@" __stringify(__LINE__) ": ", 337c3725f7cSIuliana Prodan DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg, 338c3725f7cSIuliana Prodan edesc->sec4_sg_bytes, 1); 339c3725f7cSIuliana Prodan 3408c419778STudor Ambarus return edesc; 3418c419778STudor Ambarus 3428c419778STudor Ambarus sec4_sg_fail: 3438c419778STudor Ambarus dma_unmap_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE); 3448c419778STudor Ambarus dst_fail: 3453b2614cbSIuliana Prodan dma_unmap_sg(dev, req_ctx->fixup_src, src_nents, DMA_TO_DEVICE); 3468c419778STudor Ambarus src_fail: 3478c419778STudor Ambarus kfree(edesc); 3488c419778STudor Ambarus return ERR_PTR(-ENOMEM); 3498c419778STudor Ambarus } 3508c419778STudor Ambarus 3518c419778STudor Ambarus static int set_rsa_pub_pdb(struct akcipher_request *req, 3528c419778STudor Ambarus struct rsa_edesc *edesc) 3538c419778STudor Ambarus { 3548c419778STudor Ambarus struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 3553b2614cbSIuliana Prodan struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); 3568c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 3578c419778STudor Ambarus struct caam_rsa_key *key = &ctx->key; 3588c419778STudor Ambarus struct device *dev = ctx->dev; 3598c419778STudor Ambarus struct rsa_pub_pdb *pdb = &edesc->pdb.pub; 3608c419778STudor Ambarus int sec4_sg_index = 0; 3618c419778STudor Ambarus 3628c419778STudor Ambarus pdb->n_dma = dma_map_single(dev, key->n, key->n_sz, DMA_TO_DEVICE); 3638c419778STudor Ambarus if (dma_mapping_error(dev, pdb->n_dma)) { 3648c419778STudor Ambarus dev_err(dev, "Unable to map RSA modulus memory\n"); 3658c419778STudor Ambarus return -ENOMEM; 3668c419778STudor Ambarus } 3678c419778STudor Ambarus 3688c419778STudor Ambarus pdb->e_dma = dma_map_single(dev, key->e, key->e_sz, DMA_TO_DEVICE); 3698c419778STudor Ambarus if (dma_mapping_error(dev, pdb->e_dma)) { 3708c419778STudor Ambarus dev_err(dev, "Unable to map RSA public exponent memory\n"); 3718c419778STudor Ambarus dma_unmap_single(dev, pdb->n_dma, key->n_sz, DMA_TO_DEVICE); 3728c419778STudor Ambarus return -ENOMEM; 3738c419778STudor Ambarus } 3748c419778STudor Ambarus 3758c419778STudor Ambarus if (edesc->src_nents > 1) { 3768c419778STudor Ambarus pdb->sgf |= RSA_PDB_SGF_F; 3778c419778STudor Ambarus pdb->f_dma = edesc->sec4_sg_dma; 3788c419778STudor Ambarus sec4_sg_index += edesc->src_nents; 3798c419778STudor Ambarus } else { 3803b2614cbSIuliana Prodan pdb->f_dma = sg_dma_address(req_ctx->fixup_src); 3818c419778STudor Ambarus } 3828c419778STudor Ambarus 3838c419778STudor Ambarus if (edesc->dst_nents > 1) { 3848c419778STudor Ambarus pdb->sgf |= RSA_PDB_SGF_G; 3858c419778STudor Ambarus pdb->g_dma = edesc->sec4_sg_dma + 3868c419778STudor Ambarus sec4_sg_index * sizeof(struct sec4_sg_entry); 3878c419778STudor Ambarus } else { 3888c419778STudor Ambarus pdb->g_dma = sg_dma_address(req->dst); 3898c419778STudor Ambarus } 3908c419778STudor Ambarus 3918c419778STudor Ambarus pdb->sgf |= (key->e_sz << RSA_PDB_E_SHIFT) | key->n_sz; 3923b2614cbSIuliana Prodan pdb->f_len = req_ctx->fixup_src_len; 3938c419778STudor Ambarus 3948c419778STudor Ambarus return 0; 3958c419778STudor Ambarus } 3968c419778STudor Ambarus 3978c419778STudor Ambarus static int set_rsa_priv_f1_pdb(struct akcipher_request *req, 3988c419778STudor Ambarus struct rsa_edesc *edesc) 3998c419778STudor Ambarus { 4008c419778STudor Ambarus struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 4018c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 4028c419778STudor Ambarus struct caam_rsa_key *key = &ctx->key; 4038c419778STudor Ambarus struct device *dev = ctx->dev; 4048c419778STudor Ambarus struct rsa_priv_f1_pdb *pdb = &edesc->pdb.priv_f1; 4058c419778STudor Ambarus int sec4_sg_index = 0; 4068c419778STudor Ambarus 4078c419778STudor Ambarus pdb->n_dma = dma_map_single(dev, key->n, key->n_sz, DMA_TO_DEVICE); 4088c419778STudor Ambarus if (dma_mapping_error(dev, pdb->n_dma)) { 4098c419778STudor Ambarus dev_err(dev, "Unable to map modulus memory\n"); 4108c419778STudor Ambarus return -ENOMEM; 4118c419778STudor Ambarus } 4128c419778STudor Ambarus 4138c419778STudor Ambarus pdb->d_dma = dma_map_single(dev, key->d, key->d_sz, DMA_TO_DEVICE); 4148c419778STudor Ambarus if (dma_mapping_error(dev, pdb->d_dma)) { 4158c419778STudor Ambarus dev_err(dev, "Unable to map RSA private exponent memory\n"); 4168c419778STudor Ambarus dma_unmap_single(dev, pdb->n_dma, key->n_sz, DMA_TO_DEVICE); 4178c419778STudor Ambarus return -ENOMEM; 4188c419778STudor Ambarus } 4198c419778STudor Ambarus 4208c419778STudor Ambarus if (edesc->src_nents > 1) { 4218c419778STudor Ambarus pdb->sgf |= RSA_PRIV_PDB_SGF_G; 4228c419778STudor Ambarus pdb->g_dma = edesc->sec4_sg_dma; 4238c419778STudor Ambarus sec4_sg_index += edesc->src_nents; 4248c419778STudor Ambarus } else { 4253b2614cbSIuliana Prodan struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); 4263b2614cbSIuliana Prodan 4273b2614cbSIuliana Prodan pdb->g_dma = sg_dma_address(req_ctx->fixup_src); 4288c419778STudor Ambarus } 4298c419778STudor Ambarus 4308c419778STudor Ambarus if (edesc->dst_nents > 1) { 4318c419778STudor Ambarus pdb->sgf |= RSA_PRIV_PDB_SGF_F; 4328c419778STudor Ambarus pdb->f_dma = edesc->sec4_sg_dma + 4338c419778STudor Ambarus sec4_sg_index * sizeof(struct sec4_sg_entry); 4348c419778STudor Ambarus } else { 4358c419778STudor Ambarus pdb->f_dma = sg_dma_address(req->dst); 4368c419778STudor Ambarus } 4378c419778STudor Ambarus 4388c419778STudor Ambarus pdb->sgf |= (key->d_sz << RSA_PDB_D_SHIFT) | key->n_sz; 4398c419778STudor Ambarus 4408c419778STudor Ambarus return 0; 4418c419778STudor Ambarus } 4428c419778STudor Ambarus 44352e26d77SRadu Alexe static int set_rsa_priv_f2_pdb(struct akcipher_request *req, 44452e26d77SRadu Alexe struct rsa_edesc *edesc) 44552e26d77SRadu Alexe { 44652e26d77SRadu Alexe struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 44752e26d77SRadu Alexe struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 44852e26d77SRadu Alexe struct caam_rsa_key *key = &ctx->key; 44952e26d77SRadu Alexe struct device *dev = ctx->dev; 45052e26d77SRadu Alexe struct rsa_priv_f2_pdb *pdb = &edesc->pdb.priv_f2; 45152e26d77SRadu Alexe int sec4_sg_index = 0; 45252e26d77SRadu Alexe size_t p_sz = key->p_sz; 4534bffaab3SHoria Geantă size_t q_sz = key->q_sz; 45452e26d77SRadu Alexe 45552e26d77SRadu Alexe pdb->d_dma = dma_map_single(dev, key->d, key->d_sz, DMA_TO_DEVICE); 45652e26d77SRadu Alexe if (dma_mapping_error(dev, pdb->d_dma)) { 45752e26d77SRadu Alexe dev_err(dev, "Unable to map RSA private exponent memory\n"); 45852e26d77SRadu Alexe return -ENOMEM; 45952e26d77SRadu Alexe } 46052e26d77SRadu Alexe 46152e26d77SRadu Alexe pdb->p_dma = dma_map_single(dev, key->p, p_sz, DMA_TO_DEVICE); 46252e26d77SRadu Alexe if (dma_mapping_error(dev, pdb->p_dma)) { 46352e26d77SRadu Alexe dev_err(dev, "Unable to map RSA prime factor p memory\n"); 46452e26d77SRadu Alexe goto unmap_d; 46552e26d77SRadu Alexe } 46652e26d77SRadu Alexe 46752e26d77SRadu Alexe pdb->q_dma = dma_map_single(dev, key->q, q_sz, DMA_TO_DEVICE); 46852e26d77SRadu Alexe if (dma_mapping_error(dev, pdb->q_dma)) { 46952e26d77SRadu Alexe dev_err(dev, "Unable to map RSA prime factor q memory\n"); 47052e26d77SRadu Alexe goto unmap_p; 47152e26d77SRadu Alexe } 47252e26d77SRadu Alexe 473f1bf9e60SHoria Geantă pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL); 47452e26d77SRadu Alexe if (dma_mapping_error(dev, pdb->tmp1_dma)) { 47552e26d77SRadu Alexe dev_err(dev, "Unable to map RSA tmp1 memory\n"); 47652e26d77SRadu Alexe goto unmap_q; 47752e26d77SRadu Alexe } 47852e26d77SRadu Alexe 479f1bf9e60SHoria Geantă pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL); 48052e26d77SRadu Alexe if (dma_mapping_error(dev, pdb->tmp2_dma)) { 48152e26d77SRadu Alexe dev_err(dev, "Unable to map RSA tmp2 memory\n"); 48252e26d77SRadu Alexe goto unmap_tmp1; 48352e26d77SRadu Alexe } 48452e26d77SRadu Alexe 48552e26d77SRadu Alexe if (edesc->src_nents > 1) { 48652e26d77SRadu Alexe pdb->sgf |= RSA_PRIV_PDB_SGF_G; 48752e26d77SRadu Alexe pdb->g_dma = edesc->sec4_sg_dma; 48852e26d77SRadu Alexe sec4_sg_index += edesc->src_nents; 48952e26d77SRadu Alexe } else { 4903b2614cbSIuliana Prodan struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); 4913b2614cbSIuliana Prodan 4923b2614cbSIuliana Prodan pdb->g_dma = sg_dma_address(req_ctx->fixup_src); 49352e26d77SRadu Alexe } 49452e26d77SRadu Alexe 49552e26d77SRadu Alexe if (edesc->dst_nents > 1) { 49652e26d77SRadu Alexe pdb->sgf |= RSA_PRIV_PDB_SGF_F; 49752e26d77SRadu Alexe pdb->f_dma = edesc->sec4_sg_dma + 49852e26d77SRadu Alexe sec4_sg_index * sizeof(struct sec4_sg_entry); 49952e26d77SRadu Alexe } else { 50052e26d77SRadu Alexe pdb->f_dma = sg_dma_address(req->dst); 50152e26d77SRadu Alexe } 50252e26d77SRadu Alexe 50352e26d77SRadu Alexe pdb->sgf |= (key->d_sz << RSA_PDB_D_SHIFT) | key->n_sz; 50452e26d77SRadu Alexe pdb->p_q_len = (q_sz << RSA_PDB_Q_SHIFT) | p_sz; 50552e26d77SRadu Alexe 50652e26d77SRadu Alexe return 0; 50752e26d77SRadu Alexe 50852e26d77SRadu Alexe unmap_tmp1: 509f1bf9e60SHoria Geantă dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL); 51052e26d77SRadu Alexe unmap_q: 51152e26d77SRadu Alexe dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE); 51252e26d77SRadu Alexe unmap_p: 51352e26d77SRadu Alexe dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE); 51452e26d77SRadu Alexe unmap_d: 51552e26d77SRadu Alexe dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE); 51652e26d77SRadu Alexe 51752e26d77SRadu Alexe return -ENOMEM; 51852e26d77SRadu Alexe } 51952e26d77SRadu Alexe 5204a651b12SRadu Alexe static int set_rsa_priv_f3_pdb(struct akcipher_request *req, 5214a651b12SRadu Alexe struct rsa_edesc *edesc) 5224a651b12SRadu Alexe { 5234a651b12SRadu Alexe struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 5244a651b12SRadu Alexe struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 5254a651b12SRadu Alexe struct caam_rsa_key *key = &ctx->key; 5264a651b12SRadu Alexe struct device *dev = ctx->dev; 5274a651b12SRadu Alexe struct rsa_priv_f3_pdb *pdb = &edesc->pdb.priv_f3; 5284a651b12SRadu Alexe int sec4_sg_index = 0; 5294a651b12SRadu Alexe size_t p_sz = key->p_sz; 5304bffaab3SHoria Geantă size_t q_sz = key->q_sz; 5314a651b12SRadu Alexe 5324a651b12SRadu Alexe pdb->p_dma = dma_map_single(dev, key->p, p_sz, DMA_TO_DEVICE); 5334a651b12SRadu Alexe if (dma_mapping_error(dev, pdb->p_dma)) { 5344a651b12SRadu Alexe dev_err(dev, "Unable to map RSA prime factor p memory\n"); 5354a651b12SRadu Alexe return -ENOMEM; 5364a651b12SRadu Alexe } 5374a651b12SRadu Alexe 5384a651b12SRadu Alexe pdb->q_dma = dma_map_single(dev, key->q, q_sz, DMA_TO_DEVICE); 5394a651b12SRadu Alexe if (dma_mapping_error(dev, pdb->q_dma)) { 5404a651b12SRadu Alexe dev_err(dev, "Unable to map RSA prime factor q memory\n"); 5414a651b12SRadu Alexe goto unmap_p; 5424a651b12SRadu Alexe } 5434a651b12SRadu Alexe 5444a651b12SRadu Alexe pdb->dp_dma = dma_map_single(dev, key->dp, p_sz, DMA_TO_DEVICE); 5454a651b12SRadu Alexe if (dma_mapping_error(dev, pdb->dp_dma)) { 5464a651b12SRadu Alexe dev_err(dev, "Unable to map RSA exponent dp memory\n"); 5474a651b12SRadu Alexe goto unmap_q; 5484a651b12SRadu Alexe } 5494a651b12SRadu Alexe 5504a651b12SRadu Alexe pdb->dq_dma = dma_map_single(dev, key->dq, q_sz, DMA_TO_DEVICE); 5514a651b12SRadu Alexe if (dma_mapping_error(dev, pdb->dq_dma)) { 5524a651b12SRadu Alexe dev_err(dev, "Unable to map RSA exponent dq memory\n"); 5534a651b12SRadu Alexe goto unmap_dp; 5544a651b12SRadu Alexe } 5554a651b12SRadu Alexe 5564a651b12SRadu Alexe pdb->c_dma = dma_map_single(dev, key->qinv, p_sz, DMA_TO_DEVICE); 5574a651b12SRadu Alexe if (dma_mapping_error(dev, pdb->c_dma)) { 5584a651b12SRadu Alexe dev_err(dev, "Unable to map RSA CRT coefficient qinv memory\n"); 5594a651b12SRadu Alexe goto unmap_dq; 5604a651b12SRadu Alexe } 5614a651b12SRadu Alexe 562f1bf9e60SHoria Geantă pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL); 5634a651b12SRadu Alexe if (dma_mapping_error(dev, pdb->tmp1_dma)) { 5644a651b12SRadu Alexe dev_err(dev, "Unable to map RSA tmp1 memory\n"); 5654a651b12SRadu Alexe goto unmap_qinv; 5664a651b12SRadu Alexe } 5674a651b12SRadu Alexe 568f1bf9e60SHoria Geantă pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL); 5694a651b12SRadu Alexe if (dma_mapping_error(dev, pdb->tmp2_dma)) { 5704a651b12SRadu Alexe dev_err(dev, "Unable to map RSA tmp2 memory\n"); 5714a651b12SRadu Alexe goto unmap_tmp1; 5724a651b12SRadu Alexe } 5734a651b12SRadu Alexe 5744a651b12SRadu Alexe if (edesc->src_nents > 1) { 5754a651b12SRadu Alexe pdb->sgf |= RSA_PRIV_PDB_SGF_G; 5764a651b12SRadu Alexe pdb->g_dma = edesc->sec4_sg_dma; 5774a651b12SRadu Alexe sec4_sg_index += edesc->src_nents; 5784a651b12SRadu Alexe } else { 5793b2614cbSIuliana Prodan struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); 5803b2614cbSIuliana Prodan 5813b2614cbSIuliana Prodan pdb->g_dma = sg_dma_address(req_ctx->fixup_src); 5824a651b12SRadu Alexe } 5834a651b12SRadu Alexe 5844a651b12SRadu Alexe if (edesc->dst_nents > 1) { 5854a651b12SRadu Alexe pdb->sgf |= RSA_PRIV_PDB_SGF_F; 5864a651b12SRadu Alexe pdb->f_dma = edesc->sec4_sg_dma + 5874a651b12SRadu Alexe sec4_sg_index * sizeof(struct sec4_sg_entry); 5884a651b12SRadu Alexe } else { 5894a651b12SRadu Alexe pdb->f_dma = sg_dma_address(req->dst); 5904a651b12SRadu Alexe } 5914a651b12SRadu Alexe 5924a651b12SRadu Alexe pdb->sgf |= key->n_sz; 5934a651b12SRadu Alexe pdb->p_q_len = (q_sz << RSA_PDB_Q_SHIFT) | p_sz; 5944a651b12SRadu Alexe 5954a651b12SRadu Alexe return 0; 5964a651b12SRadu Alexe 5974a651b12SRadu Alexe unmap_tmp1: 598f1bf9e60SHoria Geantă dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL); 5994a651b12SRadu Alexe unmap_qinv: 6004a651b12SRadu Alexe dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE); 6014a651b12SRadu Alexe unmap_dq: 6024a651b12SRadu Alexe dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE); 6034a651b12SRadu Alexe unmap_dp: 6044a651b12SRadu Alexe dma_unmap_single(dev, pdb->dp_dma, p_sz, DMA_TO_DEVICE); 6054a651b12SRadu Alexe unmap_q: 6064a651b12SRadu Alexe dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE); 6074a651b12SRadu Alexe unmap_p: 6084a651b12SRadu Alexe dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE); 6094a651b12SRadu Alexe 6104a651b12SRadu Alexe return -ENOMEM; 6114a651b12SRadu Alexe } 6124a651b12SRadu Alexe 6138c419778STudor Ambarus static int caam_rsa_enc(struct akcipher_request *req) 6148c419778STudor Ambarus { 6158c419778STudor Ambarus struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 6168c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 6178c419778STudor Ambarus struct caam_rsa_key *key = &ctx->key; 6188c419778STudor Ambarus struct device *jrdev = ctx->dev; 6198c419778STudor Ambarus struct rsa_edesc *edesc; 6208c419778STudor Ambarus int ret; 6218c419778STudor Ambarus 6228c419778STudor Ambarus if (unlikely(!key->n || !key->e)) 6238c419778STudor Ambarus return -EINVAL; 6248c419778STudor Ambarus 6258c419778STudor Ambarus if (req->dst_len < key->n_sz) { 6268c419778STudor Ambarus req->dst_len = key->n_sz; 6278c419778STudor Ambarus dev_err(jrdev, "Output buffer length less than parameter n\n"); 6288c419778STudor Ambarus return -EOVERFLOW; 6298c419778STudor Ambarus } 6308c419778STudor Ambarus 6318c419778STudor Ambarus /* Allocate extended descriptor */ 6328c419778STudor Ambarus edesc = rsa_edesc_alloc(req, DESC_RSA_PUB_LEN); 6338c419778STudor Ambarus if (IS_ERR(edesc)) 6348c419778STudor Ambarus return PTR_ERR(edesc); 6358c419778STudor Ambarus 6368c419778STudor Ambarus /* Set RSA Encrypt Protocol Data Block */ 6378c419778STudor Ambarus ret = set_rsa_pub_pdb(req, edesc); 6388c419778STudor Ambarus if (ret) 6398c419778STudor Ambarus goto init_fail; 6408c419778STudor Ambarus 6418c419778STudor Ambarus /* Initialize Job Descriptor */ 6428c419778STudor Ambarus init_rsa_pub_desc(edesc->hw_desc, &edesc->pdb.pub); 6438c419778STudor Ambarus 6448c419778STudor Ambarus ret = caam_jr_enqueue(jrdev, edesc->hw_desc, rsa_pub_done, req); 6458c419778STudor Ambarus if (!ret) 6468c419778STudor Ambarus return -EINPROGRESS; 6478c419778STudor Ambarus 6488c419778STudor Ambarus rsa_pub_unmap(jrdev, edesc, req); 6498c419778STudor Ambarus 6508c419778STudor Ambarus init_fail: 6518c419778STudor Ambarus rsa_io_unmap(jrdev, edesc, req); 6528c419778STudor Ambarus kfree(edesc); 6538c419778STudor Ambarus return ret; 6548c419778STudor Ambarus } 6558c419778STudor Ambarus 65652e26d77SRadu Alexe static int caam_rsa_dec_priv_f1(struct akcipher_request *req) 6578c419778STudor Ambarus { 6588c419778STudor Ambarus struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 6598c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 6608c419778STudor Ambarus struct device *jrdev = ctx->dev; 6618c419778STudor Ambarus struct rsa_edesc *edesc; 6628c419778STudor Ambarus int ret; 6638c419778STudor Ambarus 6648c419778STudor Ambarus /* Allocate extended descriptor */ 6658c419778STudor Ambarus edesc = rsa_edesc_alloc(req, DESC_RSA_PRIV_F1_LEN); 6668c419778STudor Ambarus if (IS_ERR(edesc)) 6678c419778STudor Ambarus return PTR_ERR(edesc); 6688c419778STudor Ambarus 6698c419778STudor Ambarus /* Set RSA Decrypt Protocol Data Block - Private Key Form #1 */ 6708c419778STudor Ambarus ret = set_rsa_priv_f1_pdb(req, edesc); 6718c419778STudor Ambarus if (ret) 6728c419778STudor Ambarus goto init_fail; 6738c419778STudor Ambarus 6748c419778STudor Ambarus /* Initialize Job Descriptor */ 6758c419778STudor Ambarus init_rsa_priv_f1_desc(edesc->hw_desc, &edesc->pdb.priv_f1); 6768c419778STudor Ambarus 6778c419778STudor Ambarus ret = caam_jr_enqueue(jrdev, edesc->hw_desc, rsa_priv_f1_done, req); 6788c419778STudor Ambarus if (!ret) 6798c419778STudor Ambarus return -EINPROGRESS; 6808c419778STudor Ambarus 6818c419778STudor Ambarus rsa_priv_f1_unmap(jrdev, edesc, req); 6828c419778STudor Ambarus 6838c419778STudor Ambarus init_fail: 6848c419778STudor Ambarus rsa_io_unmap(jrdev, edesc, req); 6858c419778STudor Ambarus kfree(edesc); 6868c419778STudor Ambarus return ret; 6878c419778STudor Ambarus } 6888c419778STudor Ambarus 68952e26d77SRadu Alexe static int caam_rsa_dec_priv_f2(struct akcipher_request *req) 69052e26d77SRadu Alexe { 69152e26d77SRadu Alexe struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 69252e26d77SRadu Alexe struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 69352e26d77SRadu Alexe struct device *jrdev = ctx->dev; 69452e26d77SRadu Alexe struct rsa_edesc *edesc; 69552e26d77SRadu Alexe int ret; 69652e26d77SRadu Alexe 69752e26d77SRadu Alexe /* Allocate extended descriptor */ 69852e26d77SRadu Alexe edesc = rsa_edesc_alloc(req, DESC_RSA_PRIV_F2_LEN); 69952e26d77SRadu Alexe if (IS_ERR(edesc)) 70052e26d77SRadu Alexe return PTR_ERR(edesc); 70152e26d77SRadu Alexe 70252e26d77SRadu Alexe /* Set RSA Decrypt Protocol Data Block - Private Key Form #2 */ 70352e26d77SRadu Alexe ret = set_rsa_priv_f2_pdb(req, edesc); 70452e26d77SRadu Alexe if (ret) 70552e26d77SRadu Alexe goto init_fail; 70652e26d77SRadu Alexe 70752e26d77SRadu Alexe /* Initialize Job Descriptor */ 70852e26d77SRadu Alexe init_rsa_priv_f2_desc(edesc->hw_desc, &edesc->pdb.priv_f2); 70952e26d77SRadu Alexe 71052e26d77SRadu Alexe ret = caam_jr_enqueue(jrdev, edesc->hw_desc, rsa_priv_f2_done, req); 71152e26d77SRadu Alexe if (!ret) 71252e26d77SRadu Alexe return -EINPROGRESS; 71352e26d77SRadu Alexe 71452e26d77SRadu Alexe rsa_priv_f2_unmap(jrdev, edesc, req); 71552e26d77SRadu Alexe 71652e26d77SRadu Alexe init_fail: 71752e26d77SRadu Alexe rsa_io_unmap(jrdev, edesc, req); 71852e26d77SRadu Alexe kfree(edesc); 71952e26d77SRadu Alexe return ret; 72052e26d77SRadu Alexe } 72152e26d77SRadu Alexe 7224a651b12SRadu Alexe static int caam_rsa_dec_priv_f3(struct akcipher_request *req) 7234a651b12SRadu Alexe { 7244a651b12SRadu Alexe struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 7254a651b12SRadu Alexe struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 7264a651b12SRadu Alexe struct device *jrdev = ctx->dev; 7274a651b12SRadu Alexe struct rsa_edesc *edesc; 7284a651b12SRadu Alexe int ret; 7294a651b12SRadu Alexe 7304a651b12SRadu Alexe /* Allocate extended descriptor */ 7314a651b12SRadu Alexe edesc = rsa_edesc_alloc(req, DESC_RSA_PRIV_F3_LEN); 7324a651b12SRadu Alexe if (IS_ERR(edesc)) 7334a651b12SRadu Alexe return PTR_ERR(edesc); 7344a651b12SRadu Alexe 7354a651b12SRadu Alexe /* Set RSA Decrypt Protocol Data Block - Private Key Form #3 */ 7364a651b12SRadu Alexe ret = set_rsa_priv_f3_pdb(req, edesc); 7374a651b12SRadu Alexe if (ret) 7384a651b12SRadu Alexe goto init_fail; 7394a651b12SRadu Alexe 7404a651b12SRadu Alexe /* Initialize Job Descriptor */ 7414a651b12SRadu Alexe init_rsa_priv_f3_desc(edesc->hw_desc, &edesc->pdb.priv_f3); 7424a651b12SRadu Alexe 7434a651b12SRadu Alexe ret = caam_jr_enqueue(jrdev, edesc->hw_desc, rsa_priv_f3_done, req); 7444a651b12SRadu Alexe if (!ret) 7454a651b12SRadu Alexe return -EINPROGRESS; 7464a651b12SRadu Alexe 7474a651b12SRadu Alexe rsa_priv_f3_unmap(jrdev, edesc, req); 7484a651b12SRadu Alexe 7494a651b12SRadu Alexe init_fail: 7504a651b12SRadu Alexe rsa_io_unmap(jrdev, edesc, req); 7514a651b12SRadu Alexe kfree(edesc); 7524a651b12SRadu Alexe return ret; 7534a651b12SRadu Alexe } 7544a651b12SRadu Alexe 75552e26d77SRadu Alexe static int caam_rsa_dec(struct akcipher_request *req) 75652e26d77SRadu Alexe { 75752e26d77SRadu Alexe struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 75852e26d77SRadu Alexe struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 75952e26d77SRadu Alexe struct caam_rsa_key *key = &ctx->key; 76052e26d77SRadu Alexe int ret; 76152e26d77SRadu Alexe 76252e26d77SRadu Alexe if (unlikely(!key->n || !key->d)) 76352e26d77SRadu Alexe return -EINVAL; 76452e26d77SRadu Alexe 76552e26d77SRadu Alexe if (req->dst_len < key->n_sz) { 76652e26d77SRadu Alexe req->dst_len = key->n_sz; 76752e26d77SRadu Alexe dev_err(ctx->dev, "Output buffer length less than parameter n\n"); 76852e26d77SRadu Alexe return -EOVERFLOW; 76952e26d77SRadu Alexe } 77052e26d77SRadu Alexe 7714a651b12SRadu Alexe if (key->priv_form == FORM3) 7724a651b12SRadu Alexe ret = caam_rsa_dec_priv_f3(req); 7734a651b12SRadu Alexe else if (key->priv_form == FORM2) 77452e26d77SRadu Alexe ret = caam_rsa_dec_priv_f2(req); 77552e26d77SRadu Alexe else 77652e26d77SRadu Alexe ret = caam_rsa_dec_priv_f1(req); 77752e26d77SRadu Alexe 77852e26d77SRadu Alexe return ret; 77952e26d77SRadu Alexe } 78052e26d77SRadu Alexe 7818c419778STudor Ambarus static void caam_rsa_free_key(struct caam_rsa_key *key) 7828c419778STudor Ambarus { 7838c419778STudor Ambarus kzfree(key->d); 78452e26d77SRadu Alexe kzfree(key->p); 78552e26d77SRadu Alexe kzfree(key->q); 7864a651b12SRadu Alexe kzfree(key->dp); 7874a651b12SRadu Alexe kzfree(key->dq); 7884a651b12SRadu Alexe kzfree(key->qinv); 78952e26d77SRadu Alexe kzfree(key->tmp1); 79052e26d77SRadu Alexe kzfree(key->tmp2); 7918c419778STudor Ambarus kfree(key->e); 7928c419778STudor Ambarus kfree(key->n); 79352e26d77SRadu Alexe memset(key, 0, sizeof(*key)); 7948c419778STudor Ambarus } 7958c419778STudor Ambarus 7967ca4a9a1SRadu Alexe static void caam_rsa_drop_leading_zeros(const u8 **ptr, size_t *nbytes) 7977ca4a9a1SRadu Alexe { 7987ca4a9a1SRadu Alexe while (!**ptr && *nbytes) { 7997ca4a9a1SRadu Alexe (*ptr)++; 8007ca4a9a1SRadu Alexe (*nbytes)--; 8017ca4a9a1SRadu Alexe } 8027ca4a9a1SRadu Alexe } 8037ca4a9a1SRadu Alexe 8048c419778STudor Ambarus /** 8054a651b12SRadu Alexe * caam_read_rsa_crt - Used for reading dP, dQ, qInv CRT members. 8064a651b12SRadu Alexe * dP, dQ and qInv could decode to less than corresponding p, q length, as the 8074a651b12SRadu Alexe * BER-encoding requires that the minimum number of bytes be used to encode the 8084a651b12SRadu Alexe * integer. dP, dQ, qInv decoded values have to be zero-padded to appropriate 8094a651b12SRadu Alexe * length. 8104a651b12SRadu Alexe * 8114a651b12SRadu Alexe * @ptr : pointer to {dP, dQ, qInv} CRT member 8124a651b12SRadu Alexe * @nbytes: length in bytes of {dP, dQ, qInv} CRT member 8134a651b12SRadu Alexe * @dstlen: length in bytes of corresponding p or q prime factor 8144a651b12SRadu Alexe */ 8154a651b12SRadu Alexe static u8 *caam_read_rsa_crt(const u8 *ptr, size_t nbytes, size_t dstlen) 8164a651b12SRadu Alexe { 8174a651b12SRadu Alexe u8 *dst; 8184a651b12SRadu Alexe 8194a651b12SRadu Alexe caam_rsa_drop_leading_zeros(&ptr, &nbytes); 8204a651b12SRadu Alexe if (!nbytes) 8214a651b12SRadu Alexe return NULL; 8224a651b12SRadu Alexe 8234a651b12SRadu Alexe dst = kzalloc(dstlen, GFP_DMA | GFP_KERNEL); 8244a651b12SRadu Alexe if (!dst) 8254a651b12SRadu Alexe return NULL; 8264a651b12SRadu Alexe 8274a651b12SRadu Alexe memcpy(dst + (dstlen - nbytes), ptr, nbytes); 8284a651b12SRadu Alexe 8294a651b12SRadu Alexe return dst; 8304a651b12SRadu Alexe } 8314a651b12SRadu Alexe 8324a651b12SRadu Alexe /** 8338c419778STudor Ambarus * caam_read_raw_data - Read a raw byte stream as a positive integer. 8348c419778STudor Ambarus * The function skips buffer's leading zeros, copies the remained data 8358c419778STudor Ambarus * to a buffer allocated in the GFP_DMA | GFP_KERNEL zone and returns 8368c419778STudor Ambarus * the address of the new buffer. 8378c419778STudor Ambarus * 8388c419778STudor Ambarus * @buf : The data to read 8398c419778STudor Ambarus * @nbytes: The amount of data to read 8408c419778STudor Ambarus */ 8418c419778STudor Ambarus static inline u8 *caam_read_raw_data(const u8 *buf, size_t *nbytes) 8428c419778STudor Ambarus { 8438c419778STudor Ambarus 8447ca4a9a1SRadu Alexe caam_rsa_drop_leading_zeros(&buf, nbytes); 8457fcaf62aSTudor Ambarus if (!*nbytes) 8467fcaf62aSTudor Ambarus return NULL; 8478c419778STudor Ambarus 848b930f3a2SFabio Estevam return kmemdup(buf, *nbytes, GFP_DMA | GFP_KERNEL); 8498c419778STudor Ambarus } 8508c419778STudor Ambarus 8518c419778STudor Ambarus static int caam_rsa_check_key_length(unsigned int len) 8528c419778STudor Ambarus { 8538c419778STudor Ambarus if (len > 4096) 8548c419778STudor Ambarus return -EINVAL; 8558c419778STudor Ambarus return 0; 8568c419778STudor Ambarus } 8578c419778STudor Ambarus 8588c419778STudor Ambarus static int caam_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, 8598c419778STudor Ambarus unsigned int keylen) 8608c419778STudor Ambarus { 8618c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 8628439e94fSHoria Geantă struct rsa_key raw_key = {NULL}; 8638c419778STudor Ambarus struct caam_rsa_key *rsa_key = &ctx->key; 8648c419778STudor Ambarus int ret; 8658c419778STudor Ambarus 8668c419778STudor Ambarus /* Free the old RSA key if any */ 8678c419778STudor Ambarus caam_rsa_free_key(rsa_key); 8688c419778STudor Ambarus 8698c419778STudor Ambarus ret = rsa_parse_pub_key(&raw_key, key, keylen); 8708c419778STudor Ambarus if (ret) 8718c419778STudor Ambarus return ret; 8728c419778STudor Ambarus 8738c419778STudor Ambarus /* Copy key in DMA zone */ 874cc2a58f1SFuqian Huang rsa_key->e = kmemdup(raw_key.e, raw_key.e_sz, GFP_DMA | GFP_KERNEL); 8758c419778STudor Ambarus if (!rsa_key->e) 8768c419778STudor Ambarus goto err; 8778c419778STudor Ambarus 8788c419778STudor Ambarus /* 8798c419778STudor Ambarus * Skip leading zeros and copy the positive integer to a buffer 8808c419778STudor Ambarus * allocated in the GFP_DMA | GFP_KERNEL zone. The decryption descriptor 8818c419778STudor Ambarus * expects a positive integer for the RSA modulus and uses its length as 8828c419778STudor Ambarus * decryption output length. 8838c419778STudor Ambarus */ 8848c419778STudor Ambarus rsa_key->n = caam_read_raw_data(raw_key.n, &raw_key.n_sz); 8858c419778STudor Ambarus if (!rsa_key->n) 8868c419778STudor Ambarus goto err; 8878c419778STudor Ambarus 8888c419778STudor Ambarus if (caam_rsa_check_key_length(raw_key.n_sz << 3)) { 8898c419778STudor Ambarus caam_rsa_free_key(rsa_key); 8908c419778STudor Ambarus return -EINVAL; 8918c419778STudor Ambarus } 8928c419778STudor Ambarus 8938c419778STudor Ambarus rsa_key->e_sz = raw_key.e_sz; 8948c419778STudor Ambarus rsa_key->n_sz = raw_key.n_sz; 8958c419778STudor Ambarus 8968c419778STudor Ambarus return 0; 8978c419778STudor Ambarus err: 8988c419778STudor Ambarus caam_rsa_free_key(rsa_key); 8998c419778STudor Ambarus return -ENOMEM; 9008c419778STudor Ambarus } 9018c419778STudor Ambarus 90252e26d77SRadu Alexe static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, 90352e26d77SRadu Alexe struct rsa_key *raw_key) 90452e26d77SRadu Alexe { 90552e26d77SRadu Alexe struct caam_rsa_key *rsa_key = &ctx->key; 90652e26d77SRadu Alexe size_t p_sz = raw_key->p_sz; 90752e26d77SRadu Alexe size_t q_sz = raw_key->q_sz; 90852e26d77SRadu Alexe 90952e26d77SRadu Alexe rsa_key->p = caam_read_raw_data(raw_key->p, &p_sz); 91052e26d77SRadu Alexe if (!rsa_key->p) 91152e26d77SRadu Alexe return; 91252e26d77SRadu Alexe rsa_key->p_sz = p_sz; 91352e26d77SRadu Alexe 91452e26d77SRadu Alexe rsa_key->q = caam_read_raw_data(raw_key->q, &q_sz); 91552e26d77SRadu Alexe if (!rsa_key->q) 91652e26d77SRadu Alexe goto free_p; 91752e26d77SRadu Alexe rsa_key->q_sz = q_sz; 91852e26d77SRadu Alexe 91952e26d77SRadu Alexe rsa_key->tmp1 = kzalloc(raw_key->p_sz, GFP_DMA | GFP_KERNEL); 92052e26d77SRadu Alexe if (!rsa_key->tmp1) 92152e26d77SRadu Alexe goto free_q; 92252e26d77SRadu Alexe 92352e26d77SRadu Alexe rsa_key->tmp2 = kzalloc(raw_key->q_sz, GFP_DMA | GFP_KERNEL); 92452e26d77SRadu Alexe if (!rsa_key->tmp2) 92552e26d77SRadu Alexe goto free_tmp1; 92652e26d77SRadu Alexe 92752e26d77SRadu Alexe rsa_key->priv_form = FORM2; 92852e26d77SRadu Alexe 9294a651b12SRadu Alexe rsa_key->dp = caam_read_rsa_crt(raw_key->dp, raw_key->dp_sz, p_sz); 9304a651b12SRadu Alexe if (!rsa_key->dp) 9314a651b12SRadu Alexe goto free_tmp2; 9324a651b12SRadu Alexe 9334a651b12SRadu Alexe rsa_key->dq = caam_read_rsa_crt(raw_key->dq, raw_key->dq_sz, q_sz); 9344a651b12SRadu Alexe if (!rsa_key->dq) 9354a651b12SRadu Alexe goto free_dp; 9364a651b12SRadu Alexe 9374a651b12SRadu Alexe rsa_key->qinv = caam_read_rsa_crt(raw_key->qinv, raw_key->qinv_sz, 9384a651b12SRadu Alexe q_sz); 9394a651b12SRadu Alexe if (!rsa_key->qinv) 9404a651b12SRadu Alexe goto free_dq; 9414a651b12SRadu Alexe 9424a651b12SRadu Alexe rsa_key->priv_form = FORM3; 9434a651b12SRadu Alexe 94452e26d77SRadu Alexe return; 94552e26d77SRadu Alexe 9464a651b12SRadu Alexe free_dq: 9474a651b12SRadu Alexe kzfree(rsa_key->dq); 9484a651b12SRadu Alexe free_dp: 9494a651b12SRadu Alexe kzfree(rsa_key->dp); 9504a651b12SRadu Alexe free_tmp2: 9514a651b12SRadu Alexe kzfree(rsa_key->tmp2); 95252e26d77SRadu Alexe free_tmp1: 95352e26d77SRadu Alexe kzfree(rsa_key->tmp1); 95452e26d77SRadu Alexe free_q: 95552e26d77SRadu Alexe kzfree(rsa_key->q); 95652e26d77SRadu Alexe free_p: 95752e26d77SRadu Alexe kzfree(rsa_key->p); 95852e26d77SRadu Alexe } 95952e26d77SRadu Alexe 9608c419778STudor Ambarus static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, 9618c419778STudor Ambarus unsigned int keylen) 9628c419778STudor Ambarus { 9638c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 9648439e94fSHoria Geantă struct rsa_key raw_key = {NULL}; 9658c419778STudor Ambarus struct caam_rsa_key *rsa_key = &ctx->key; 9668c419778STudor Ambarus int ret; 9678c419778STudor Ambarus 9688c419778STudor Ambarus /* Free the old RSA key if any */ 9698c419778STudor Ambarus caam_rsa_free_key(rsa_key); 9708c419778STudor Ambarus 9718c419778STudor Ambarus ret = rsa_parse_priv_key(&raw_key, key, keylen); 9728c419778STudor Ambarus if (ret) 9738c419778STudor Ambarus return ret; 9748c419778STudor Ambarus 9758c419778STudor Ambarus /* Copy key in DMA zone */ 976cc2a58f1SFuqian Huang rsa_key->d = kmemdup(raw_key.d, raw_key.d_sz, GFP_DMA | GFP_KERNEL); 9778c419778STudor Ambarus if (!rsa_key->d) 9788c419778STudor Ambarus goto err; 9798c419778STudor Ambarus 980cc2a58f1SFuqian Huang rsa_key->e = kmemdup(raw_key.e, raw_key.e_sz, GFP_DMA | GFP_KERNEL); 9818c419778STudor Ambarus if (!rsa_key->e) 9828c419778STudor Ambarus goto err; 9838c419778STudor Ambarus 9848c419778STudor Ambarus /* 9858c419778STudor Ambarus * Skip leading zeros and copy the positive integer to a buffer 9868c419778STudor Ambarus * allocated in the GFP_DMA | GFP_KERNEL zone. The decryption descriptor 9878c419778STudor Ambarus * expects a positive integer for the RSA modulus and uses its length as 9888c419778STudor Ambarus * decryption output length. 9898c419778STudor Ambarus */ 9908c419778STudor Ambarus rsa_key->n = caam_read_raw_data(raw_key.n, &raw_key.n_sz); 9918c419778STudor Ambarus if (!rsa_key->n) 9928c419778STudor Ambarus goto err; 9938c419778STudor Ambarus 9948c419778STudor Ambarus if (caam_rsa_check_key_length(raw_key.n_sz << 3)) { 9958c419778STudor Ambarus caam_rsa_free_key(rsa_key); 9968c419778STudor Ambarus return -EINVAL; 9978c419778STudor Ambarus } 9988c419778STudor Ambarus 9998c419778STudor Ambarus rsa_key->d_sz = raw_key.d_sz; 10008c419778STudor Ambarus rsa_key->e_sz = raw_key.e_sz; 10018c419778STudor Ambarus rsa_key->n_sz = raw_key.n_sz; 10028c419778STudor Ambarus 100352e26d77SRadu Alexe caam_rsa_set_priv_key_form(ctx, &raw_key); 100452e26d77SRadu Alexe 10058c419778STudor Ambarus return 0; 10068c419778STudor Ambarus 10078c419778STudor Ambarus err: 10088c419778STudor Ambarus caam_rsa_free_key(rsa_key); 10098c419778STudor Ambarus return -ENOMEM; 10108c419778STudor Ambarus } 10118c419778STudor Ambarus 1012e198429cSTudor-Dan Ambarus static unsigned int caam_rsa_max_size(struct crypto_akcipher *tfm) 10138c419778STudor Ambarus { 10148c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 10158c419778STudor Ambarus 1016e198429cSTudor-Dan Ambarus return ctx->key.n_sz; 10178c419778STudor Ambarus } 10188c419778STudor Ambarus 10198c419778STudor Ambarus /* Per session pkc's driver context creation function */ 10208c419778STudor Ambarus static int caam_rsa_init_tfm(struct crypto_akcipher *tfm) 10218c419778STudor Ambarus { 10228c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 10238c419778STudor Ambarus 10248c419778STudor Ambarus ctx->dev = caam_jr_alloc(); 10258c419778STudor Ambarus 10268c419778STudor Ambarus if (IS_ERR(ctx->dev)) { 102733fa46d7SHoria Geantă pr_err("Job Ring Device allocation for transform failed\n"); 10288c419778STudor Ambarus return PTR_ERR(ctx->dev); 10298c419778STudor Ambarus } 10308c419778STudor Ambarus 1031c3725f7cSIuliana Prodan ctx->padding_dma = dma_map_single(ctx->dev, zero_buffer, 1032c3725f7cSIuliana Prodan CAAM_RSA_MAX_INPUT_SIZE - 1, 1033c3725f7cSIuliana Prodan DMA_TO_DEVICE); 1034c3725f7cSIuliana Prodan if (dma_mapping_error(ctx->dev, ctx->padding_dma)) { 1035c3725f7cSIuliana Prodan dev_err(ctx->dev, "unable to map padding\n"); 1036c3725f7cSIuliana Prodan caam_jr_free(ctx->dev); 1037c3725f7cSIuliana Prodan return -ENOMEM; 1038c3725f7cSIuliana Prodan } 1039c3725f7cSIuliana Prodan 10408c419778STudor Ambarus return 0; 10418c419778STudor Ambarus } 10428c419778STudor Ambarus 10438c419778STudor Ambarus /* Per session pkc's driver context cleanup function */ 10448c419778STudor Ambarus static void caam_rsa_exit_tfm(struct crypto_akcipher *tfm) 10458c419778STudor Ambarus { 10468c419778STudor Ambarus struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); 10478c419778STudor Ambarus struct caam_rsa_key *key = &ctx->key; 10488c419778STudor Ambarus 1049c3725f7cSIuliana Prodan dma_unmap_single(ctx->dev, ctx->padding_dma, CAAM_RSA_MAX_INPUT_SIZE - 1050c3725f7cSIuliana Prodan 1, DMA_TO_DEVICE); 10518c419778STudor Ambarus caam_rsa_free_key(key); 10528c419778STudor Ambarus caam_jr_free(ctx->dev); 10538c419778STudor Ambarus } 10548c419778STudor Ambarus 10558c419778STudor Ambarus static struct akcipher_alg caam_rsa = { 10568c419778STudor Ambarus .encrypt = caam_rsa_enc, 10578c419778STudor Ambarus .decrypt = caam_rsa_dec, 10588c419778STudor Ambarus .set_pub_key = caam_rsa_set_pub_key, 10598c419778STudor Ambarus .set_priv_key = caam_rsa_set_priv_key, 10608c419778STudor Ambarus .max_size = caam_rsa_max_size, 10618c419778STudor Ambarus .init = caam_rsa_init_tfm, 10628c419778STudor Ambarus .exit = caam_rsa_exit_tfm, 10638a2a0dd3SHoria Geantă .reqsize = sizeof(struct caam_rsa_req_ctx), 10648c419778STudor Ambarus .base = { 10658c419778STudor Ambarus .cra_name = "rsa", 10668c419778STudor Ambarus .cra_driver_name = "rsa-caam", 10678c419778STudor Ambarus .cra_priority = 3000, 10688c419778STudor Ambarus .cra_module = THIS_MODULE, 10698c419778STudor Ambarus .cra_ctxsize = sizeof(struct caam_rsa_ctx), 10708c419778STudor Ambarus }, 10718c419778STudor Ambarus }; 10728c419778STudor Ambarus 10738c419778STudor Ambarus /* Public Key Cryptography module initialization handler */ 10741b46c90cSHoria Geantă int caam_pkc_init(struct device *ctrldev) 10758c419778STudor Ambarus { 10761b46c90cSHoria Geantă struct caam_drv_private *priv = dev_get_drvdata(ctrldev); 1077d239b10dSHoria Geantă u32 pk_inst; 10788c419778STudor Ambarus int err; 10798c419778STudor Ambarus 10808c419778STudor Ambarus /* Determine public key hardware accelerator presence. */ 1081d239b10dSHoria Geantă if (priv->era < 10) 1082d239b10dSHoria Geantă pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & 1083d239b10dSHoria Geantă CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT; 1084d239b10dSHoria Geantă else 1085d239b10dSHoria Geantă pk_inst = rd_reg32(&priv->ctrl->vreg.pkha) & CHA_VER_NUM_MASK; 10868c419778STudor Ambarus 10878c419778STudor Ambarus /* Do not register algorithms if PKHA is not present. */ 10881b46c90cSHoria Geantă if (!pk_inst) 10891b46c90cSHoria Geantă return 0; 10908c419778STudor Ambarus 1091c3725f7cSIuliana Prodan /* allocate zero buffer, used for padding input */ 1092c3725f7cSIuliana Prodan zero_buffer = kzalloc(CAAM_RSA_MAX_INPUT_SIZE - 1, GFP_DMA | 1093c3725f7cSIuliana Prodan GFP_KERNEL); 1094c3725f7cSIuliana Prodan if (!zero_buffer) 1095c3725f7cSIuliana Prodan return -ENOMEM; 1096c3725f7cSIuliana Prodan 10978c419778STudor Ambarus err = crypto_register_akcipher(&caam_rsa); 1098c3725f7cSIuliana Prodan if (err) { 1099c3725f7cSIuliana Prodan kfree(zero_buffer); 11008c419778STudor Ambarus dev_warn(ctrldev, "%s alg registration failed\n", 11018c419778STudor Ambarus caam_rsa.base.cra_driver_name); 1102c3725f7cSIuliana Prodan } else { 11038c419778STudor Ambarus dev_info(ctrldev, "caam pkc algorithms registered in /proc/crypto\n"); 1104c3725f7cSIuliana Prodan } 11058c419778STudor Ambarus 11068c419778STudor Ambarus return err; 11078c419778STudor Ambarus } 11088c419778STudor Ambarus 11091b46c90cSHoria Geantă void caam_pkc_exit(void) 11108c419778STudor Ambarus { 1111c3725f7cSIuliana Prodan kfree(zero_buffer); 11128c419778STudor Ambarus crypto_unregister_akcipher(&caam_rsa); 11138c419778STudor Ambarus } 1114