Commit 3b2614cb authored by Iuliana Prodan's avatar Iuliana Prodan Committed by Herbert Xu

crypto: caam - strip input without changing crypto request

For rsa and pkcs1pad, CAAM expects an input of modulus size.
For this we strip the leading zeros in case the size is more than modulus.
This commit avoids modifying the crypto request while stripping zeros from
input, to comply with the crypto API requirement. This is done by adding
a fixup input pointer and length.
Signed-off-by: default avatarIuliana Prodan <iuliana.prodan@nxp.com>
Reviewed-by: default avatarHoria Geanta <horia.geanta@nxp.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent c3725f7c
...@@ -32,8 +32,10 @@ static u8 *zero_buffer; ...@@ -32,8 +32,10 @@ static u8 *zero_buffer;
static void rsa_io_unmap(struct device *dev, struct rsa_edesc *edesc, static void rsa_io_unmap(struct device *dev, struct rsa_edesc *edesc,
struct akcipher_request *req) struct akcipher_request *req)
{ {
struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req);
dma_unmap_sg(dev, req->dst, edesc->dst_nents, DMA_FROM_DEVICE); dma_unmap_sg(dev, req->dst, edesc->dst_nents, DMA_FROM_DEVICE);
dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE); dma_unmap_sg(dev, req_ctx->fixup_src, edesc->src_nents, DMA_TO_DEVICE);
if (edesc->sec4_sg_bytes) if (edesc->sec4_sg_bytes)
dma_unmap_single(dev, edesc->sec4_sg_dma, edesc->sec4_sg_bytes, dma_unmap_single(dev, edesc->sec4_sg_dma, edesc->sec4_sg_bytes,
...@@ -251,17 +253,21 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req, ...@@ -251,17 +253,21 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req,
if (lzeros < 0) if (lzeros < 0)
return ERR_PTR(lzeros); return ERR_PTR(lzeros);
req->src_len -= lzeros; req_ctx->fixup_src = scatterwalk_ffwd(req_ctx->src, req->src,
req->src = scatterwalk_ffwd(req_ctx->src, req->src, lzeros); lzeros);
req_ctx->fixup_src_len = req->src_len - lzeros;
} else { } else {
/* /*
* input src is less then n key modulus, * input src is less then n key modulus,
* so there will be zero padding * so there will be zero padding
*/ */
diff_size = key->n_sz - req->src_len; diff_size = key->n_sz - req->src_len;
req_ctx->fixup_src = req->src;
req_ctx->fixup_src_len = req->src_len;
} }
src_nents = sg_nents_for_len(req->src, req->src_len); src_nents = sg_nents_for_len(req_ctx->fixup_src,
req_ctx->fixup_src_len);
dst_nents = sg_nents_for_len(req->dst, req->dst_len); dst_nents = sg_nents_for_len(req->dst, req->dst_len);
if (!diff_size && src_nents == 1) if (!diff_size && src_nents == 1)
...@@ -282,7 +288,7 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req, ...@@ -282,7 +288,7 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req,
if (!edesc) if (!edesc)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
sgc = dma_map_sg(dev, req->src, src_nents, DMA_TO_DEVICE); sgc = dma_map_sg(dev, req_ctx->fixup_src, src_nents, DMA_TO_DEVICE);
if (unlikely(!sgc)) { if (unlikely(!sgc)) {
dev_err(dev, "unable to map source\n"); dev_err(dev, "unable to map source\n");
goto src_fail; goto src_fail;
...@@ -300,8 +306,8 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req, ...@@ -300,8 +306,8 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req,
0); 0);
if (sec4_sg_index) if (sec4_sg_index)
sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg + sg_to_sec4_sg_last(req_ctx->fixup_src, src_nents,
!!diff_size, 0); edesc->sec4_sg + !!diff_size, 0);
if (dst_nents > 1) if (dst_nents > 1)
sg_to_sec4_sg_last(req->dst, dst_nents, sg_to_sec4_sg_last(req->dst, dst_nents,
...@@ -332,7 +338,7 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req, ...@@ -332,7 +338,7 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req,
sec4_sg_fail: sec4_sg_fail:
dma_unmap_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE); dma_unmap_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE);
dst_fail: dst_fail:
dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE); dma_unmap_sg(dev, req_ctx->fixup_src, src_nents, DMA_TO_DEVICE);
src_fail: src_fail:
kfree(edesc); kfree(edesc);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -342,6 +348,7 @@ static int set_rsa_pub_pdb(struct akcipher_request *req, ...@@ -342,6 +348,7 @@ static int set_rsa_pub_pdb(struct akcipher_request *req,
struct rsa_edesc *edesc) struct rsa_edesc *edesc)
{ {
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req);
struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
struct caam_rsa_key *key = &ctx->key; struct caam_rsa_key *key = &ctx->key;
struct device *dev = ctx->dev; struct device *dev = ctx->dev;
...@@ -366,7 +373,7 @@ static int set_rsa_pub_pdb(struct akcipher_request *req, ...@@ -366,7 +373,7 @@ static int set_rsa_pub_pdb(struct akcipher_request *req,
pdb->f_dma = edesc->sec4_sg_dma; pdb->f_dma = edesc->sec4_sg_dma;
sec4_sg_index += edesc->src_nents; sec4_sg_index += edesc->src_nents;
} else { } else {
pdb->f_dma = sg_dma_address(req->src); pdb->f_dma = sg_dma_address(req_ctx->fixup_src);
} }
if (edesc->dst_nents > 1) { if (edesc->dst_nents > 1) {
...@@ -378,7 +385,7 @@ static int set_rsa_pub_pdb(struct akcipher_request *req, ...@@ -378,7 +385,7 @@ static int set_rsa_pub_pdb(struct akcipher_request *req,
} }
pdb->sgf |= (key->e_sz << RSA_PDB_E_SHIFT) | key->n_sz; pdb->sgf |= (key->e_sz << RSA_PDB_E_SHIFT) | key->n_sz;
pdb->f_len = req->src_len; pdb->f_len = req_ctx->fixup_src_len;
return 0; return 0;
} }
...@@ -411,7 +418,9 @@ static int set_rsa_priv_f1_pdb(struct akcipher_request *req, ...@@ -411,7 +418,9 @@ static int set_rsa_priv_f1_pdb(struct akcipher_request *req,
pdb->g_dma = edesc->sec4_sg_dma; pdb->g_dma = edesc->sec4_sg_dma;
sec4_sg_index += edesc->src_nents; sec4_sg_index += edesc->src_nents;
} else { } else {
pdb->g_dma = sg_dma_address(req->src); struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req);
pdb->g_dma = sg_dma_address(req_ctx->fixup_src);
} }
if (edesc->dst_nents > 1) { if (edesc->dst_nents > 1) {
...@@ -474,7 +483,9 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req, ...@@ -474,7 +483,9 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
pdb->g_dma = edesc->sec4_sg_dma; pdb->g_dma = edesc->sec4_sg_dma;
sec4_sg_index += edesc->src_nents; sec4_sg_index += edesc->src_nents;
} else { } else {
pdb->g_dma = sg_dma_address(req->src); struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req);
pdb->g_dma = sg_dma_address(req_ctx->fixup_src);
} }
if (edesc->dst_nents > 1) { if (edesc->dst_nents > 1) {
...@@ -561,7 +572,9 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req, ...@@ -561,7 +572,9 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
pdb->g_dma = edesc->sec4_sg_dma; pdb->g_dma = edesc->sec4_sg_dma;
sec4_sg_index += edesc->src_nents; sec4_sg_index += edesc->src_nents;
} else { } else {
pdb->g_dma = sg_dma_address(req->src); struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req);
pdb->g_dma = sg_dma_address(req_ctx->fixup_src);
} }
if (edesc->dst_nents > 1) { if (edesc->dst_nents > 1) {
......
...@@ -95,14 +95,19 @@ struct caam_rsa_ctx { ...@@ -95,14 +95,19 @@ struct caam_rsa_ctx {
struct caam_rsa_key key; struct caam_rsa_key key;
struct device *dev; struct device *dev;
dma_addr_t padding_dma; dma_addr_t padding_dma;
}; };
/** /**
* caam_rsa_req_ctx - per request context. * caam_rsa_req_ctx - per request context.
* @src: input scatterlist (stripped of leading zeros) * @src : input scatterlist (stripped of leading zeros)
* @fixup_src : input scatterlist (that might be stripped of leading zeros)
* @fixup_src_len : length of the fixup_src input scatterlist
*/ */
struct caam_rsa_req_ctx { struct caam_rsa_req_ctx {
struct scatterlist src[2]; struct scatterlist src[2];
struct scatterlist *fixup_src;
unsigned int fixup_src_len;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment