diff options
author | Devulapally Shiva Krishna <shiva@chelsio.com> | 2020-05-05 08:42:53 +0530 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-05-06 17:44:11 -0700 |
commit | d91a3159e8d9a1bf58c2aaad1ef10a09bc91350c (patch) | |
tree | 0347a03d3b041a845f7042dadb995f10fc19ed96 /drivers/crypto/chelsio/chcr_algo.c | |
parent | 33395f4a5c1b68a4eaa49af62ff3bbed71d98598 (diff) | |
download | linux-d91a3159e8d9a1bf58c2aaad1ef10a09bc91350c.tar.bz2 |
Crypto/chcr: fix gcm-aes and rfc4106-gcm failed tests
This patch fixes two issues observed during self tests with
CONFIG_CRYPTO_MANAGER_EXTRA_TESTS enabled.
1. gcm(aes) hang issue , that happens during decryption.
2. rfc4106-gcm-aes-chcr encryption unexpectedly succeeded.
For gcm-aes decryption , authtag is not mapped due to
sg_nents_for_len(upto size: assoclen+ cryptlen - authsize).
So fix it by dma_mapping authtag.
Also replaced sg_nents() to sg_nents_for_len() in case of aead_dma_unmap().
For rfc4106-gcm-aes-chcr, used crypto_ipsec_check_assoclen() for checking
the validity of assoclen.
Signed-off-by: Ayush Sawal <ayush.sawal@chelsio.com>
Signed-off-by: Devulapally Shiva Krishna <shiva@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/crypto/chelsio/chcr_algo.c')
-rw-r--r-- | drivers/crypto/chelsio/chcr_algo.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c index c29b80dd30d8..e300eb32a9d3 100644 --- a/drivers/crypto/chelsio/chcr_algo.c +++ b/drivers/crypto/chelsio/chcr_algo.c @@ -2556,7 +2556,7 @@ int chcr_aead_dma_map(struct device *dev, int dst_size; dst_size = req->assoclen + req->cryptlen + (op_type ? - -authsize : authsize); + 0 : authsize); if (!req->cryptlen || !dst_size) return 0; reqctx->iv_dma = dma_map_single(dev, reqctx->iv, (IV + reqctx->b0_len), @@ -2603,15 +2603,16 @@ void chcr_aead_dma_unmap(struct device *dev, int dst_size; dst_size = req->assoclen + req->cryptlen + (op_type ? - -authsize : authsize); + 0 : authsize); if (!req->cryptlen || !dst_size) return; dma_unmap_single(dev, reqctx->iv_dma, (IV + reqctx->b0_len), DMA_BIDIRECTIONAL); if (req->src == req->dst) { - dma_unmap_sg(dev, req->src, sg_nents(req->src), - DMA_BIDIRECTIONAL); + dma_unmap_sg(dev, req->src, + sg_nents_for_len(req->src, dst_size), + DMA_BIDIRECTIONAL); } else { dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE); @@ -3702,6 +3703,13 @@ static int chcr_aead_op(struct aead_request *req, return -ENOSPC; } + if (get_aead_subtype(tfm) == CRYPTO_ALG_SUB_TYPE_AEAD_RFC4106 && + crypto_ipsec_check_assoclen(req->assoclen) != 0) { + pr_err("RFC4106: Invalid value of assoclen %d\n", + req->assoclen); + return -EINVAL; + } + /* Form a WR from req */ skb = create_wr_fn(req, u_ctx->lldi.rxq_ids[reqctx->rxqidx], size); |