]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Crypto/chcr: fix gcm-aes and rfc4106-gcm failed tests
authorDevulapally Shiva Krishna <shiva@chelsio.com>
Tue, 5 May 2020 03:12:53 +0000 (08:42 +0530)
committerDavid S. Miller <davem@davemloft.net>
Thu, 7 May 2020 00:44:11 +0000 (17:44 -0700)
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>
drivers/crypto/chelsio/chcr_algo.c

index c29b80dd30d86c5a332654fdb6f5748883d497a8..e300eb32a9d33c8a12e757c55c4cb95dde726a97 100644 (file)
@@ -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);