diff options
author | Cristian Stoica <cristian.stoica@freescale.com> | 2014-12-05 12:33:17 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:41:54 (GMT) |
commit | 258b7f66e2cc7e7f60327c717e8abb8e6523dbf2 (patch) | |
tree | da9c720de84b574b9c4dd54f10cb380f5d2fe4ec /drivers/crypto/caam | |
parent | ada621a433512b120c8baff0e7793935396f6e45 (diff) | |
download | linux-fsl-qoriq-258b7f66e2cc7e7f60327c717e8abb8e6523dbf2.tar.xz |
crypto: caam: fix encryption with null assoc data
This is a fix for caam gcm offloading failure through cryptodev. If
assoc data is null, the driver crashes:
Modules linked in: cryptodev
CPU: 3 PID: 1930 Comm: openssl Not tainted
3.12.19-rt30-QorIQ-SDK-V1.7+gcebf692 #4
task: e9061070 ti: ebe72000 task.ti: ebe72000
NIP: c04ea360 LR: c04eed54 CTR: c04ef530
REGS: ebe73ba0 TRAP: 0300 Not tainted
(3.12.19-rt30-QorIQ-SDK-V1.7+gcebf692)
MSR: 00029002 <CE,EE,ME> CR: 44242484 XER: 00000000
DEAR: 00000000, ESR: 00000000
GPR00: c04eed54 ebe73c50 e9061070 eb41ea10 00000000 00000001 00000001 00000000
GPR08: 00000020 00000000 00000000 00000002 44242482 10089738 10081750 100633f8
GPR16: 100813fc 00000000 000000d1 ebe73cd8 0000000c bfc8e9c4 bfc8de54 eb41ea10
GPR24: eb896a00 c087dbe0 00000001 00000000 eb41ea10 00000001 00000000 00000000
NIP [c04ea360] dma_map_sg_chained+0x50/0x180
LR [c04eed54] aead_edesc_alloc.constprop.19+0x164/0x940
Call Trace:
[ebe73c50] [84244482] 0x84244482 (unreliable)
[ebe73c80] [c04eed54] aead_edesc_alloc.constprop.19+0x164/0x940
[ebe73cd0] [c04ef55c] aead_encrypt+0x2c/0xd0
[ebe73d00] [f9523c2c] cryptodev_cipher_encrypt+0xcc/0x140 [cryptodev]
[ebe73d10] [f952561c] crypto_auth_run+0x2ec/0xbd0 [cryptodev]
[ebe73d80] [f95227a0] cryptodev_ioctl+0x500/0xa10 [cryptodev]
[ebe73eb0] [c0107a40] do_vfs_ioctl+0x4d0/0x780
[ebe73f10] [c0107d30] SyS_ioctl+0x40/0x80
[ebe73f40] [c000fbcc] ret_from_syscall+0x0/0x3c
--- Exception: c01 at 0xfcc308c
LR = 0xfd5f064
Instruction dump:
91810010 7cbd2b78 7cda3378 40de0098 2f830000 41de0138 832300b0 2f9d0000
7f7edb78 3be00000 40dd002c 60000000 <807e0000> 3bff0001 5463003a
4bbe2855
---[ end trace 08c4f2b427249be6 ]---
Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
Change-Id: I6554d83dbc9acb089f2dce5ff4f1044642262b03
Reviewed-on: http://git.am.freescale.net:8181/25433
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
Reviewed-by: Matthew Weigel <Matthew.Weigel@freescale.com>
Diffstat (limited to 'drivers/crypto/caam')
-rw-r--r-- | drivers/crypto/caam/caamalg.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index d52867f..6335139 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -2647,7 +2647,7 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, in_options = 0; } else { src_dma = edesc->sec4_sg_dma; - sec4_sg_index += (edesc->assoc_nents ? : 1) + 1 + + sec4_sg_index += edesc->assoc_nents + 1 + (edesc->src_nents ? : 1); in_options = LDST_SGF; } @@ -2660,7 +2660,7 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, dst_dma = sg_dma_address(req->src); } else { dst_dma = src_dma + sizeof(struct sec4_sg_entry) * - ((edesc->assoc_nents ? : 1) + 1); + (edesc->assoc_nents + 1); out_options = LDST_SGF; } } else { @@ -2917,7 +2917,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, unsigned int authsize = ctx->authsize; bool is_gcm = false; - assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); + assoc_nents = __sg_count(req->assoc, req->assoclen, &assoc_chained); if (unlikely(req->dst != req->src)) { int extralen; @@ -2936,9 +2936,9 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, (encrypt ? authsize : 0), &src_chained); } - - sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, - DMA_TO_DEVICE, assoc_chained); + if (req->assoclen) + sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents, + DMA_TO_DEVICE, assoc_chained); if (likely(req->src == req->dst)) { sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, DMA_BIDIRECTIONAL, src_chained); @@ -2966,16 +2966,15 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, * All other - expected input sequence: AAD, IV, text */ if (is_gcm) - all_contig = (!assoc_nents && + all_contig = ((assoc_nents == 1) && iv_dma + ivsize == sg_dma_address(req->assoc) && !src_nents && sg_dma_address(req->assoc) + req->assoclen == sg_dma_address(req->src)); else - all_contig = (!assoc_nents && sg_dma_address(req->assoc) + + all_contig = ((assoc_nents == 1) && sg_dma_address(req->assoc) + req->assoclen == iv_dma && !src_nents && iv_dma + ivsize == sg_dma_address(req->src)); if (!all_contig) { - assoc_nents = assoc_nents ? : 1; src_nents = src_nents ? : 1; sec4_sg_len = assoc_nents + 1 + src_nents; } @@ -3006,7 +3005,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, sec4_sg_index = 0; if (!all_contig) { - if (!is_gcm) { + if (!is_gcm && assoc_nents) { sg_to_sec4_sg(req->assoc, assoc_nents, edesc->sec4_sg + sec4_sg_index, @@ -3018,7 +3017,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, iv_dma, ivsize, 0); sec4_sg_index += 1; - if (is_gcm) { + if (is_gcm && assoc_nents) { sg_to_sec4_sg(req->assoc, assoc_nents, edesc->sec4_sg + sec4_sg_index, |