aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-11-24 09:01:42 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2008-12-24 19:01:54 -0500
commit5df4c0c671bbb425e4a77dde5f51869aeebebd67 (patch)
treea302e5c58642b8c22f0ceafbdfcba100f8c96c79
parent3416158680d5ba6fdb939e5bb52a8eba1ad5c027 (diff)
crypto: hifn_795x - Fix request context corruption
HIFN uses the transform context to store per-request data, which breaks when more than one request is outstanding. Move per request members from struct hifn_context to a new struct hifn_request_context and convert the code to use this. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/hifn_795x.c100
1 files changed, 56 insertions, 44 deletions
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 2b4940bc8356..97a77d7baca4 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -657,9 +657,15 @@ struct ablkcipher_walk
657 657
658struct hifn_context 658struct hifn_context
659{ 659{
660 u8 key[HIFN_MAX_CRYPT_KEY_LENGTH], *iv; 660 u8 key[HIFN_MAX_CRYPT_KEY_LENGTH];
661 struct hifn_device *dev; 661 struct hifn_device *dev;
662 unsigned int keysize, ivsize; 662 unsigned int keysize;
663};
664
665struct hifn_request_context
666{
667 u8 *iv;
668 unsigned int ivsize;
663 u8 op, type, mode, unused; 669 u8 op, type, mode, unused;
664 struct ablkcipher_walk walk; 670 struct ablkcipher_walk walk;
665}; 671};
@@ -1167,7 +1173,8 @@ static int hifn_setup_crypto_command(struct hifn_device *dev,
1167} 1173}
1168 1174
1169static int hifn_setup_cmd_desc(struct hifn_device *dev, 1175static int hifn_setup_cmd_desc(struct hifn_device *dev,
1170 struct hifn_context *ctx, void *priv, unsigned int nbytes) 1176 struct hifn_context *ctx, struct hifn_request_context *rctx,
1177 void *priv, unsigned int nbytes)
1171{ 1178{
1172 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; 1179 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1173 int cmd_len, sa_idx; 1180 int cmd_len, sa_idx;
@@ -1178,7 +1185,7 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1178 buf_pos = buf = dma->command_bufs[dma->cmdi]; 1185 buf_pos = buf = dma->command_bufs[dma->cmdi];
1179 1186
1180 mask = 0; 1187 mask = 0;
1181 switch (ctx->op) { 1188 switch (rctx->op) {
1182 case ACRYPTO_OP_DECRYPT: 1189 case ACRYPTO_OP_DECRYPT:
1183 mask = HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE; 1190 mask = HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE;
1184 break; 1191 break;
@@ -1195,15 +1202,15 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1195 buf_pos += hifn_setup_base_command(dev, buf_pos, nbytes, 1202 buf_pos += hifn_setup_base_command(dev, buf_pos, nbytes,
1196 nbytes, mask, dev->snum); 1203 nbytes, mask, dev->snum);
1197 1204
1198 if (ctx->op == ACRYPTO_OP_ENCRYPT || ctx->op == ACRYPTO_OP_DECRYPT) { 1205 if (rctx->op == ACRYPTO_OP_ENCRYPT || rctx->op == ACRYPTO_OP_DECRYPT) {
1199 u16 md = 0; 1206 u16 md = 0;
1200 1207
1201 if (ctx->keysize) 1208 if (ctx->keysize)
1202 md |= HIFN_CRYPT_CMD_NEW_KEY; 1209 md |= HIFN_CRYPT_CMD_NEW_KEY;
1203 if (ctx->iv && ctx->mode != ACRYPTO_MODE_ECB) 1210 if (rctx->iv && rctx->mode != ACRYPTO_MODE_ECB)
1204 md |= HIFN_CRYPT_CMD_NEW_IV; 1211 md |= HIFN_CRYPT_CMD_NEW_IV;
1205 1212
1206 switch (ctx->mode) { 1213 switch (rctx->mode) {
1207 case ACRYPTO_MODE_ECB: 1214 case ACRYPTO_MODE_ECB:
1208 md |= HIFN_CRYPT_CMD_MODE_ECB; 1215 md |= HIFN_CRYPT_CMD_MODE_ECB;
1209 break; 1216 break;
@@ -1220,7 +1227,7 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1220 goto err_out; 1227 goto err_out;
1221 } 1228 }
1222 1229
1223 switch (ctx->type) { 1230 switch (rctx->type) {
1224 case ACRYPTO_TYPE_AES_128: 1231 case ACRYPTO_TYPE_AES_128:
1225 if (ctx->keysize != 16) 1232 if (ctx->keysize != 16)
1226 goto err_out; 1233 goto err_out;
@@ -1255,7 +1262,7 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1255 1262
1256 buf_pos += hifn_setup_crypto_command(dev, buf_pos, 1263 buf_pos += hifn_setup_crypto_command(dev, buf_pos,
1257 nbytes, nbytes, ctx->key, ctx->keysize, 1264 nbytes, nbytes, ctx->key, ctx->keysize,
1258 ctx->iv, ctx->ivsize, md); 1265 rctx->iv, rctx->ivsize, md);
1259 } 1266 }
1260 1267
1261 dev->sa[sa_idx] = priv; 1268 dev->sa[sa_idx] = priv;
@@ -1265,7 +1272,7 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1265 HIFN_D_LAST | HIFN_D_MASKDONEIRQ); 1272 HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
1266 1273
1267 if (++dma->cmdi == HIFN_D_CMD_RSIZE) { 1274 if (++dma->cmdi == HIFN_D_CMD_RSIZE) {
1268 dma->cmdr[dma->cmdi].l = __cpu_to_le32(HIFN_MAX_COMMAND | 1275 dma->cmdr[dma->cmdi].l = __cpu_to_le32(
1269 HIFN_D_VALID | HIFN_D_LAST | 1276 HIFN_D_VALID | HIFN_D_LAST |
1270 HIFN_D_MASKDONEIRQ | HIFN_D_JUMP); 1277 HIFN_D_MASKDONEIRQ | HIFN_D_JUMP);
1271 dma->cmdi = 0; 1278 dma->cmdi = 0;
@@ -1369,7 +1376,8 @@ static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page,
1369 } 1376 }
1370} 1377}
1371 1378
1372static int hifn_setup_dma(struct hifn_device *dev, struct hifn_context *ctx, 1379static int hifn_setup_dma(struct hifn_device *dev,
1380 struct hifn_context *ctx, struct hifn_request_context *rctx,
1373 struct scatterlist *src, struct scatterlist *dst, 1381 struct scatterlist *src, struct scatterlist *dst,
1374 unsigned int nbytes, void *priv) 1382 unsigned int nbytes, void *priv)
1375{ 1383{
@@ -1385,18 +1393,18 @@ static int hifn_setup_dma(struct hifn_device *dev, struct hifn_context *ctx,
1385 len = min(src->length, n); 1393 len = min(src->length, n);
1386 1394
1387 dprintk("%s: spage: %p, soffset: %u, nbytes: %u, " 1395 dprintk("%s: spage: %p, soffset: %u, nbytes: %u, "
1388 "priv: %p, ctx: %p.\n", 1396 "priv: %p, rctx: %p.\n",
1389 dev->name, spage, soff, nbytes, priv, ctx); 1397 dev->name, spage, soff, nbytes, priv, rctx);
1390 hifn_setup_src_desc(dev, spage, soff, len, n - len == 0); 1398 hifn_setup_src_desc(dev, spage, soff, len, n - len == 0);
1391 1399
1392 src++; 1400 src++;
1393 n -= len; 1401 n -= len;
1394 } 1402 }
1395 1403
1396 t = &ctx->walk.cache[0]; 1404 t = &rctx->walk.cache[0];
1397 n = nbytes; 1405 n = nbytes;
1398 while (n) { 1406 while (n) {
1399 if (t->length) { 1407 if (t->length && rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
1400 dpage = sg_page(t); 1408 dpage = sg_page(t);
1401 doff = 0; 1409 doff = 0;
1402 len = t->length; 1410 len = t->length;
@@ -1408,8 +1416,8 @@ static int hifn_setup_dma(struct hifn_device *dev, struct hifn_context *ctx,
1408 len = min(len, n); 1416 len = min(len, n);
1409 1417
1410 dprintk("%s: dpage: %p, doffset: %u, nbytes: %u, " 1418 dprintk("%s: dpage: %p, doffset: %u, nbytes: %u, "
1411 "priv: %p, ctx: %p.\n", 1419 "priv: %p, rctx: %p.\n",
1412 dev->name, dpage, doff, nbytes, priv, ctx); 1420 dev->name, dpage, doff, nbytes, priv, rctx);
1413 hifn_setup_dst_desc(dev, dpage, doff, len, n - len == 0); 1421 hifn_setup_dst_desc(dev, dpage, doff, len, n - len == 0);
1414 1422
1415 dst++; 1423 dst++;
@@ -1417,7 +1425,7 @@ static int hifn_setup_dma(struct hifn_device *dev, struct hifn_context *ctx,
1417 n -= len; 1425 n -= len;
1418 } 1426 }
1419 1427
1420 hifn_setup_cmd_desc(dev, ctx, priv, nbytes); 1428 hifn_setup_cmd_desc(dev, ctx, rctx, priv, nbytes);
1421 hifn_setup_res_desc(dev); 1429 hifn_setup_res_desc(dev);
1422 return 0; 1430 return 0;
1423} 1431}
@@ -1580,16 +1588,17 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1580static int hifn_setup_session(struct ablkcipher_request *req) 1588static int hifn_setup_session(struct ablkcipher_request *req)
1581{ 1589{
1582 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); 1590 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
1591 struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
1583 struct hifn_device *dev = ctx->dev; 1592 struct hifn_device *dev = ctx->dev;
1584 unsigned long dlen, flags; 1593 unsigned long dlen, flags;
1585 unsigned int nbytes = req->nbytes, idx = 0; 1594 unsigned int nbytes = req->nbytes, idx = 0;
1586 int err = -EINVAL, sg_num; 1595 int err = -EINVAL, sg_num;
1587 struct scatterlist *dst; 1596 struct scatterlist *dst;
1588 1597
1589 if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB) 1598 if (rctx->iv && !rctx->ivsize && rctx->mode != ACRYPTO_MODE_ECB)
1590 goto err_out_exit; 1599 goto err_out_exit;
1591 1600
1592 ctx->walk.flags = 0; 1601 rctx->walk.flags = 0;
1593 1602
1594 while (nbytes) { 1603 while (nbytes) {
1595 dst = &req->dst[idx]; 1604 dst = &req->dst[idx];
@@ -1597,19 +1606,19 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1597 1606
1598 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || 1607 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
1599 !IS_ALIGNED(dlen, HIFN_D_DST_DALIGN)) 1608 !IS_ALIGNED(dlen, HIFN_D_DST_DALIGN))
1600 ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED; 1609 rctx->walk.flags |= ASYNC_FLAGS_MISALIGNED;
1601 1610
1602 nbytes -= dlen; 1611 nbytes -= dlen;
1603 idx++; 1612 idx++;
1604 } 1613 }
1605 1614
1606 if (ctx->walk.flags & ASYNC_FLAGS_MISALIGNED) { 1615 if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
1607 err = ablkcipher_walk_init(&ctx->walk, idx, GFP_ATOMIC); 1616 err = ablkcipher_walk_init(&rctx->walk, idx, GFP_ATOMIC);
1608 if (err < 0) 1617 if (err < 0)
1609 return err; 1618 return err;
1610 } 1619 }
1611 1620
1612 sg_num = ablkcipher_walk(req, &ctx->walk); 1621 sg_num = ablkcipher_walk(req, &rctx->walk);
1613 if (sg_num < 0) { 1622 if (sg_num < 0) {
1614 err = sg_num; 1623 err = sg_num;
1615 goto err_out_exit; 1624 goto err_out_exit;
@@ -1624,7 +1633,7 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1624 dev->snum++; 1633 dev->snum++;
1625 dev->started++; 1634 dev->started++;
1626 1635
1627 err = hifn_setup_dma(dev, ctx, req->src, req->dst, req->nbytes, req); 1636 err = hifn_setup_dma(dev, ctx, rctx, req->src, req->dst, req->nbytes, req);
1628 if (err) 1637 if (err)
1629 goto err_out; 1638 goto err_out;
1630 1639
@@ -1639,9 +1648,9 @@ err_out_exit:
1639 if (err) 1648 if (err)
1640 dprintk("%s: iv: %p [%d], key: %p [%d], mode: %u, op: %u, " 1649 dprintk("%s: iv: %p [%d], key: %p [%d], mode: %u, op: %u, "
1641 "type: %u, err: %d.\n", 1650 "type: %u, err: %d.\n",
1642 dev->name, ctx->iv, ctx->ivsize, 1651 dev->name, rctx->iv, rctx->ivsize,
1643 ctx->key, ctx->keysize, 1652 ctx->key, ctx->keysize,
1644 ctx->mode, ctx->op, ctx->type, err); 1653 rctx->mode, rctx->op, rctx->type, err);
1645 1654
1646 return err; 1655 return err;
1647} 1656}
@@ -1651,6 +1660,7 @@ static int hifn_test(struct hifn_device *dev, int encdec, u8 snum)
1651 int n, err; 1660 int n, err;
1652 u8 src[16]; 1661 u8 src[16];
1653 struct hifn_context ctx; 1662 struct hifn_context ctx;
1663 struct hifn_request_context rctx;
1654 u8 fips_aes_ecb_from_zero[16] = { 1664 u8 fips_aes_ecb_from_zero[16] = {
1655 0x66, 0xE9, 0x4B, 0xD4, 1665 0x66, 0xE9, 0x4B, 0xD4,
1656 0xEF, 0x8A, 0x2C, 0x3B, 1666 0xEF, 0x8A, 0x2C, 0x3B,
@@ -1663,16 +1673,16 @@ static int hifn_test(struct hifn_device *dev, int encdec, u8 snum)
1663 1673
1664 ctx.dev = dev; 1674 ctx.dev = dev;
1665 ctx.keysize = 16; 1675 ctx.keysize = 16;
1666 ctx.ivsize = 0; 1676 rctx.ivsize = 0;
1667 ctx.iv = NULL; 1677 rctx.iv = NULL;
1668 ctx.op = (encdec)?ACRYPTO_OP_ENCRYPT:ACRYPTO_OP_DECRYPT; 1678 rctx.op = (encdec)?ACRYPTO_OP_ENCRYPT:ACRYPTO_OP_DECRYPT;
1669 ctx.mode = ACRYPTO_MODE_ECB; 1679 rctx.mode = ACRYPTO_MODE_ECB;
1670 ctx.type = ACRYPTO_TYPE_AES_128; 1680 rctx.type = ACRYPTO_TYPE_AES_128;
1671 ctx.walk.cache[0].length = 0; 1681 rctx.walk.cache[0].length = 0;
1672 1682
1673 sg_init_one(&sg, &src, sizeof(src)); 1683 sg_init_one(&sg, &src, sizeof(src));
1674 1684
1675 err = hifn_setup_dma(dev, &ctx, &sg, &sg, sizeof(src), NULL); 1685 err = hifn_setup_dma(dev, &ctx, &rctx, &sg, &sg, sizeof(src), NULL);
1676 if (err) 1686 if (err)
1677 goto err_out; 1687 goto err_out;
1678 1688
@@ -1758,9 +1768,10 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset
1758static void hifn_process_ready(struct ablkcipher_request *req, int error) 1768static void hifn_process_ready(struct ablkcipher_request *req, int error)
1759{ 1769{
1760 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); 1770 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
1771 struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
1761 struct hifn_device *dev; 1772 struct hifn_device *dev;
1762 1773
1763 dprintk("%s: req: %p, ctx: %p.\n", __func__, req, ctx); 1774 dprintk("%s: req: %p, ctx: %p rctx: %p.\n", __func__, req, ctx, rctx);
1764 1775
1765 dev = ctx->dev; 1776 dev = ctx->dev;
1766 dprintk("%s: req: %p, started: %d.\n", __func__, req, dev->started); 1777 dprintk("%s: req: %p, started: %d.\n", __func__, req, dev->started);
@@ -1768,14 +1779,14 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
1768 if (--dev->started < 0) 1779 if (--dev->started < 0)
1769 BUG(); 1780 BUG();
1770 1781
1771 if (ctx->walk.flags & ASYNC_FLAGS_MISALIGNED) { 1782 if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
1772 unsigned int nbytes = req->nbytes; 1783 unsigned int nbytes = req->nbytes;
1773 int idx = 0, err; 1784 int idx = 0, err;
1774 struct scatterlist *dst, *t; 1785 struct scatterlist *dst, *t;
1775 void *saddr; 1786 void *saddr;
1776 1787
1777 while (nbytes) { 1788 while (nbytes) {
1778 t = &ctx->walk.cache[idx]; 1789 t = &rctx->walk.cache[idx];
1779 dst = &req->dst[idx]; 1790 dst = &req->dst[idx];
1780 1791
1781 dprintk("\n%s: sg_page(t): %p, t->length: %u, " 1792 dprintk("\n%s: sg_page(t): %p, t->length: %u, "
@@ -1803,7 +1814,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
1803 kunmap_atomic(saddr, KM_IRQ1); 1814 kunmap_atomic(saddr, KM_IRQ1);
1804 } 1815 }
1805 1816
1806 ablkcipher_walk_exit(&ctx->walk); 1817 ablkcipher_walk_exit(&rctx->walk);
1807 } 1818 }
1808 1819
1809 req->base.complete(&req->base, error); 1820 req->base.complete(&req->base, error);
@@ -2109,6 +2120,7 @@ static int hifn_setup_crypto_req(struct ablkcipher_request *req, u8 op,
2109 u8 type, u8 mode) 2120 u8 type, u8 mode)
2110{ 2121{
2111 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); 2122 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
2123 struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
2112 unsigned ivsize; 2124 unsigned ivsize;
2113 2125
2114 ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req)); 2126 ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req));
@@ -2129,11 +2141,11 @@ static int hifn_setup_crypto_req(struct ablkcipher_request *req, u8 op,
2129 type = ACRYPTO_TYPE_AES_256; 2141 type = ACRYPTO_TYPE_AES_256;
2130 } 2142 }
2131 2143
2132 ctx->op = op; 2144 rctx->op = op;
2133 ctx->mode = mode; 2145 rctx->mode = mode;
2134 ctx->type = type; 2146 rctx->type = type;
2135 ctx->iv = req->info; 2147 rctx->iv = req->info;
2136 ctx->ivsize = ivsize; 2148 rctx->ivsize = ivsize;
2137 2149
2138 /* 2150 /*
2139 * HEAVY TODO: needs to kick Herbert XU to write documentation. 2151 * HEAVY TODO: needs to kick Herbert XU to write documentation.
@@ -2484,7 +2496,7 @@ static int hifn_cra_init(struct crypto_tfm *tfm)
2484 struct hifn_context *ctx = crypto_tfm_ctx(tfm); 2496 struct hifn_context *ctx = crypto_tfm_ctx(tfm);
2485 2497
2486 ctx->dev = ha->dev; 2498 ctx->dev = ha->dev;
2487 2499 tfm->crt_ablkcipher.reqsize = sizeof(struct hifn_request_context);
2488 return 0; 2500 return 0;
2489} 2501}
2490 2502