xref: /linux/drivers/crypto/caam/caampkc.c (revision 1984aaeec372fbfb597883074253d290cbd543d4)
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