diff options
author | Horia Geanta <horia.geanta@freescale.com> | 2013-11-19 14:57:49 +0200 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2013-11-28 22:25:16 +0800 |
commit | 935e99a3afda0a58c2eada0ff7c613d3844d738c (patch) | |
tree | 45fca0e326613e4ae8143c195ae00d6358d43b10 | |
parent | 41da8b5adba77e22584f8b45f9641504fa885308 (diff) |
crypto: talitos - corrrectly handle zero-length assoc data
talitos does not handle well zero-length assoc data. From dmesg:
talitos ffe30000.crypto: master data transfer error
talitos ffe30000.crypto: gather return/length error
Check whether assoc data is provided by inspecting assoclen,
not assoc pointer.
This is needed in order to pass testmgr tests.
Signed-off-by: Horia Geanta <horia.geanta@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | drivers/crypto/talitos.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 905de4427e7..81ab42cd14b 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -790,7 +790,7 @@ static void ipsec_esp_unmap(struct device *dev, if (edesc->assoc_chained) talitos_unmap_sg_chain(dev, areq->assoc, DMA_TO_DEVICE); - else + else if (areq->assoclen) /* assoc_nents counts also for IV in non-contiguous cases */ dma_unmap_sg(dev, areq->assoc, edesc->assoc_nents ? edesc->assoc_nents - 1 : 1, @@ -973,7 +973,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, dma_sync_single_for_device(dev, edesc->dma_link_tbl, edesc->dma_len, DMA_BIDIRECTIONAL); } else { - to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->assoc)); + if (areq->assoclen) + to_talitos_ptr(&desc->ptr[1], + sg_dma_address(areq->assoc)); + else + to_talitos_ptr(&desc->ptr[1], edesc->iv_dma); desc->ptr[1].j_extent = 0; } @@ -1122,10 +1126,10 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, return ERR_PTR(-EINVAL); } - if (iv) + if (ivsize) iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE); - if (assoc) { + if (assoclen) { /* * Currently it is assumed that iv is provided whenever assoc * is. @@ -1173,9 +1177,16 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, edesc = kmalloc(alloc_len, GFP_DMA | flags); if (!edesc) { - talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE); + if (assoc_chained) + talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE); + else if (assoclen) + dma_unmap_sg(dev, assoc, + assoc_nents ? assoc_nents - 1 : 1, + DMA_TO_DEVICE); + if (iv_dma) dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE); + dev_err(dev, "could not allocate edescriptor\n"); return ERR_PTR(-ENOMEM); } |