| From a9bacfcf7f86f2c0adcd207f091564a911b50a7b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 5 May 2021 20:26:09 +0000 |
| Subject: crypto: ixp4xx - update IV after requests |
| |
| From: Corentin Labbe <clabbe@baylibre.com> |
| |
| [ Upstream commit e8acf011f2e7e21a7e2fae47cbaa06598e533d40 ] |
| |
| Crypto selftests fail on ixp4xx since it do not update IV after skcipher |
| requests. |
| |
| Fixes: 81bef0150074 ("crypto: ixp4xx - Hardware crypto support for IXP4xx CPUs") |
| Signed-off-by: Corentin Labbe <clabbe@baylibre.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/crypto/ixp4xx_crypto.c | 22 ++++++++++++++++++++++ |
| 1 file changed, 22 insertions(+) |
| |
| diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c |
| index cbb1fda299a8..5e474a7a1912 100644 |
| --- a/drivers/crypto/ixp4xx_crypto.c |
| +++ b/drivers/crypto/ixp4xx_crypto.c |
| @@ -149,6 +149,8 @@ struct crypt_ctl { |
| struct ablk_ctx { |
| struct buffer_desc *src; |
| struct buffer_desc *dst; |
| + u8 iv[MAX_IVLEN]; |
| + bool encrypt; |
| }; |
| |
| struct aead_ctx { |
| @@ -381,6 +383,20 @@ static void one_packet(dma_addr_t phys) |
| case CTL_FLAG_PERFORM_ABLK: { |
| struct skcipher_request *req = crypt->data.ablk_req; |
| struct ablk_ctx *req_ctx = skcipher_request_ctx(req); |
| + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); |
| + unsigned int ivsize = crypto_skcipher_ivsize(tfm); |
| + unsigned int offset; |
| + |
| + if (ivsize > 0) { |
| + offset = req->cryptlen - ivsize; |
| + if (req_ctx->encrypt) { |
| + scatterwalk_map_and_copy(req->iv, req->dst, |
| + offset, ivsize, 0); |
| + } else { |
| + memcpy(req->iv, req_ctx->iv, ivsize); |
| + memzero_explicit(req_ctx->iv, ivsize); |
| + } |
| + } |
| |
| if (req_ctx->dst) { |
| free_buf_chain(dev, req_ctx->dst, crypt->dst_buf); |
| @@ -876,6 +892,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) |
| struct ablk_ctx *req_ctx = skcipher_request_ctx(req); |
| struct buffer_desc src_hook; |
| struct device *dev = &pdev->dev; |
| + unsigned int offset; |
| gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? |
| GFP_KERNEL : GFP_ATOMIC; |
| |
| @@ -885,6 +902,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) |
| return -EAGAIN; |
| |
| dir = encrypt ? &ctx->encrypt : &ctx->decrypt; |
| + req_ctx->encrypt = encrypt; |
| |
| crypt = get_crypt_desc(); |
| if (!crypt) |
| @@ -900,6 +918,10 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) |
| |
| BUG_ON(ivsize && !req->iv); |
| memcpy(crypt->iv, req->iv, ivsize); |
| + if (ivsize > 0 && !encrypt) { |
| + offset = req->cryptlen - ivsize; |
| + scatterwalk_map_and_copy(req_ctx->iv, req->src, offset, ivsize, 0); |
| + } |
| if (req->src != req->dst) { |
| struct buffer_desc dst_hook; |
| crypt->mode |= NPE_OP_NOT_IN_PLACE; |
| -- |
| 2.30.2 |
| |