diff options
Diffstat (limited to 'drivers/crypto/hifn_795x.c')
-rw-r--r-- | drivers/crypto/hifn_795x.c | 100 |
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 | ||
658 | struct hifn_context | 658 | struct 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 | |||
665 | struct 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 | ||
1169 | static int hifn_setup_cmd_desc(struct hifn_device *dev, | 1175 | static 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 | ||
1372 | static int hifn_setup_dma(struct hifn_device *dev, struct hifn_context *ctx, | 1379 | static 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, | |||
1580 | static int hifn_setup_session(struct ablkcipher_request *req) | 1588 | static 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 | |||
1758 | static void hifn_process_ready(struct ablkcipher_request *req, int error) | 1768 | static 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 | ||