aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHoria Geanta <horia.geanta@freescale.com>2013-11-28 08:11:17 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2013-11-28 09:25:17 -0500
commit62293a37de0138b2e9c965f0a3b803c0f40a6581 (patch)
treef8377cd7005898d69a4bb8fc38d620ad112dd736
parentbbf9c8934ba2bfd5fd809562f945deaf5a565898 (diff)
crypto: talitos - fix aead sglen for case 'dst != src'
For aead case when source and destination buffers are different, there is an incorrect assumption that the source length includes the ICV length. Fix this, since it leads to an oops when using sg_count() to find the number of nents in the scatterlist: Unable to handle kernel paging request for data at address 0x00000004 Faulting instruction address: 0xf2265a28 Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=8 P2020 RDB Modules linked in: talitos(+) CPU: 1 PID: 2187 Comm: cryptomgr_test Not tainted 3.11.0 #12 task: c4e72e20 ti: ef634000 task.ti: ef634000 NIP: f2265a28 LR: f2266ad8 CTR: c000c900 REGS: ef635bb0 TRAP: 0300 Not tainted (3.11.0) MSR: 00029000 <CE,EE,ME> CR: 42042084 XER: 00000000 DEAR: 00000004, ESR: 00000000 GPR00: f2266e10 ef635c60 c4e72e20 00000001 00000014 ef635c69 00000001 c11f3082 GPR08: 00000010 00000000 00000002 2f635d58 22044084 00000000 00000000 c0755c80 GPR16: c4bf1000 ef784000 00000000 00000000 00000020 00000014 00000010 ef2f6100 GPR24: ef2f6200 00000024 ef143210 ef2f6000 00000000 ef635d58 00000000 2f635d58 NIP [f2265a28] sg_count+0x1c/0xb4 [talitos] LR [f2266ad8] talitos_edesc_alloc+0x12c/0x410 [talitos] Call Trace: [ef635c60] [c0552068] schedule_timeout+0x148/0x1ac (unreliable) [ef635cc0] [f2266e10] aead_edesc_alloc+0x54/0x64 [talitos] [ef635ce0] [f22680f0] aead_encrypt+0x24/0x70 [talitos] [ef635cf0] [c024b948] __test_aead+0x494/0xf68 [ef635e20] [c024d54c] test_aead+0x64/0xcc [ef635e40] [c024d604] alg_test_aead+0x50/0xc4 [ef635e60] [c024c838] alg_test+0x10c/0x2e4 [ef635ee0] [c0249d1c] cryptomgr_test+0x4c/0x54 [ef635ef0] [c005d598] kthread+0xa8/0xac [ef635f40] [c000e3bc] ret_from_kernel_thread+0x5c/0x64 Instruction dump: 81230024 552807fe 0f080000 5523003a 4bffff24 39000000 2c040000 99050000 408100a0 7c691b78 38c00001 38600000 <80e90004> 38630001 8109000c 70ea0002 ---[ end trace 4498123cd8478591 ]--- 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.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 81ab42cd14b2..b44f4ddc565c 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1112,7 +1112,8 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1112 unsigned int authsize, 1112 unsigned int authsize,
1113 unsigned int ivsize, 1113 unsigned int ivsize,
1114 int icv_stashing, 1114 int icv_stashing,
1115 u32 cryptoflags) 1115 u32 cryptoflags,
1116 bool encrypt)
1116{ 1117{
1117 struct talitos_edesc *edesc; 1118 struct talitos_edesc *edesc;
1118 int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len; 1119 int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len;
@@ -1145,19 +1146,17 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1145 assoc_nents = assoc_nents ? assoc_nents + 1 : 2; 1146 assoc_nents = assoc_nents ? assoc_nents + 1 : 2;
1146 } 1147 }
1147 1148
1148 src_nents = sg_count(src, cryptlen + authsize, &src_chained); 1149 if (!dst || dst == src) {
1149 src_nents = (src_nents == 1) ? 0 : src_nents; 1150 src_nents = sg_count(src, cryptlen + authsize, &src_chained);
1150 1151 src_nents = (src_nents == 1) ? 0 : src_nents;
1151 if (!dst) { 1152 dst_nents = dst ? src_nents : 0;
1152 dst_nents = 0; 1153 } else { /* dst && dst != src*/
1153 } else { 1154 src_nents = sg_count(src, cryptlen + (encrypt ? 0 : authsize),
1154 if (dst == src) { 1155 &src_chained);
1155 dst_nents = src_nents; 1156 src_nents = (src_nents == 1) ? 0 : src_nents;
1156 } else { 1157 dst_nents = sg_count(dst, cryptlen + (encrypt ? authsize : 0),
1157 dst_nents = sg_count(dst, cryptlen + authsize, 1158 &dst_chained);
1158 &dst_chained); 1159 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
1159 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
1160 }
1161 } 1160 }
1162 1161
1163 /* 1162 /*
@@ -1208,7 +1207,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1208} 1207}
1209 1208
1210static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv, 1209static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
1211 int icv_stashing) 1210 int icv_stashing, bool encrypt)
1212{ 1211{
1213 struct crypto_aead *authenc = crypto_aead_reqtfm(areq); 1212 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
1214 struct talitos_ctx *ctx = crypto_aead_ctx(authenc); 1213 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
@@ -1217,7 +1216,7 @@ static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
1217 return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst, 1216 return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst,
1218 iv, areq->assoclen, areq->cryptlen, 1217 iv, areq->assoclen, areq->cryptlen,
1219 ctx->authsize, ivsize, icv_stashing, 1218 ctx->authsize, ivsize, icv_stashing,
1220 areq->base.flags); 1219 areq->base.flags, encrypt);
1221} 1220}
1222 1221
1223static int aead_encrypt(struct aead_request *req) 1222static int aead_encrypt(struct aead_request *req)
@@ -1227,7 +1226,7 @@ static int aead_encrypt(struct aead_request *req)
1227 struct talitos_edesc *edesc; 1226 struct talitos_edesc *edesc;
1228 1227
1229 /* allocate extended descriptor */ 1228 /* allocate extended descriptor */
1230 edesc = aead_edesc_alloc(req, req->iv, 0); 1229 edesc = aead_edesc_alloc(req, req->iv, 0, true);
1231 if (IS_ERR(edesc)) 1230 if (IS_ERR(edesc))
1232 return PTR_ERR(edesc); 1231 return PTR_ERR(edesc);
1233 1232
@@ -1250,7 +1249,7 @@ static int aead_decrypt(struct aead_request *req)
1250 req->cryptlen -= authsize; 1249 req->cryptlen -= authsize;
1251 1250
1252 /* allocate extended descriptor */ 1251 /* allocate extended descriptor */
1253 edesc = aead_edesc_alloc(req, req->iv, 1); 1252 edesc = aead_edesc_alloc(req, req->iv, 1, false);
1254 if (IS_ERR(edesc)) 1253 if (IS_ERR(edesc))
1255 return PTR_ERR(edesc); 1254 return PTR_ERR(edesc);
1256 1255
@@ -1296,7 +1295,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *req)
1296 struct talitos_edesc *edesc; 1295 struct talitos_edesc *edesc;
1297 1296
1298 /* allocate extended descriptor */ 1297 /* allocate extended descriptor */
1299 edesc = aead_edesc_alloc(areq, req->giv, 0); 1298 edesc = aead_edesc_alloc(areq, req->giv, 0, true);
1300 if (IS_ERR(edesc)) 1299 if (IS_ERR(edesc))
1301 return PTR_ERR(edesc); 1300 return PTR_ERR(edesc);
1302 1301
@@ -1452,7 +1451,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
1452} 1451}
1453 1452
1454static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request * 1453static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
1455 areq) 1454 areq, bool encrypt)
1456{ 1455{
1457 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); 1456 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1458 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); 1457 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
@@ -1460,7 +1459,7 @@ static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
1460 1459
1461 return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst, 1460 return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst,
1462 areq->info, 0, areq->nbytes, 0, ivsize, 0, 1461 areq->info, 0, areq->nbytes, 0, ivsize, 0,
1463 areq->base.flags); 1462 areq->base.flags, encrypt);
1464} 1463}
1465 1464
1466static int ablkcipher_encrypt(struct ablkcipher_request *areq) 1465static int ablkcipher_encrypt(struct ablkcipher_request *areq)
@@ -1470,7 +1469,7 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1470 struct talitos_edesc *edesc; 1469 struct talitos_edesc *edesc;
1471 1470
1472 /* allocate extended descriptor */ 1471 /* allocate extended descriptor */
1473 edesc = ablkcipher_edesc_alloc(areq); 1472 edesc = ablkcipher_edesc_alloc(areq, true);
1474 if (IS_ERR(edesc)) 1473 if (IS_ERR(edesc))
1475 return PTR_ERR(edesc); 1474 return PTR_ERR(edesc);
1476 1475
@@ -1487,7 +1486,7 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1487 struct talitos_edesc *edesc; 1486 struct talitos_edesc *edesc;
1488 1487
1489 /* allocate extended descriptor */ 1488 /* allocate extended descriptor */
1490 edesc = ablkcipher_edesc_alloc(areq); 1489 edesc = ablkcipher_edesc_alloc(areq, false);
1491 if (IS_ERR(edesc)) 1490 if (IS_ERR(edesc))
1492 return PTR_ERR(edesc); 1491 return PTR_ERR(edesc);
1493 1492
@@ -1639,7 +1638,7 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1639 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 1638 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1640 1639
1641 return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0, 1640 return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0,
1642 nbytes, 0, 0, 0, areq->base.flags); 1641 nbytes, 0, 0, 0, areq->base.flags, false);
1643} 1642}
1644 1643
1645static int ahash_init(struct ahash_request *areq) 1644static int ahash_init(struct ahash_request *areq)