aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-05-07 10:33:37 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-07-10 08:35:11 -0400
commitd069033b42b392662320f71e319296a14d57ff3a (patch)
treeed7ba912d8a4079b24424a444dc73aafb9a1548c /drivers
parent94eaa1bd7ca67e8f57919da96cbb41c215ef20cb (diff)
[HIFN]: Fix data alignment checks
The check for misalignment of the scatterlist data has two bugs: - the source buffer doesn't need to be aligned at all - the destination buffer and its size needs to be aligned to a multiple of 4, not to the crypto alg blocksize Introduce symbolic constant for destination buffer alignment requirements, use it instead of the crypto alg blocksize and remove the unnecessary checks for source buffer alignment and change cra_alignmask to zero. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/crypto/hifn_795x.c42
1 files changed, 14 insertions, 28 deletions
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 4e89cd8f664f..4428e8e68a0d 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -369,6 +369,8 @@ static atomic_t hifn_dev_number;
369#define HIFN_D_DST_RSIZE 80*4 369#define HIFN_D_DST_RSIZE 80*4
370#define HIFN_D_RES_RSIZE 24*4 370#define HIFN_D_RES_RSIZE 24*4
371 371
372#define HIFN_D_DST_DALIGN 4
373
372#define HIFN_QUEUE_LENGTH HIFN_D_CMD_RSIZE-5 374#define HIFN_QUEUE_LENGTH HIFN_D_CMD_RSIZE-5
373 375
374#define AES_MIN_KEY_SIZE 16 376#define AES_MIN_KEY_SIZE 16
@@ -1458,10 +1460,6 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist
1458static int ablkcipher_walk(struct ablkcipher_request *req, 1460static int ablkcipher_walk(struct ablkcipher_request *req,
1459 struct ablkcipher_walk *w) 1461 struct ablkcipher_walk *w)
1460{ 1462{
1461 unsigned blocksize =
1462 crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(req));
1463 unsigned alignmask =
1464 crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req));
1465 struct scatterlist *src, *dst, *t; 1463 struct scatterlist *src, *dst, *t;
1466 void *daddr; 1464 void *daddr;
1467 unsigned int nbytes = req->nbytes, offset, copy, diff; 1465 unsigned int nbytes = req->nbytes, offset, copy, diff;
@@ -1477,15 +1475,13 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1477 dst = &req->dst[idx]; 1475 dst = &req->dst[idx];
1478 1476
1479 dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, " 1477 dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, "
1480 "blocksize: %u, nbytes: %u.\n", 1478 "nbytes: %u.\n",
1481 __func__, src->length, dst->length, src->offset, 1479 __func__, src->length, dst->length, src->offset,
1482 dst->offset, offset, blocksize, nbytes); 1480 dst->offset, offset, nbytes);
1483 1481
1484 if (src->length & (blocksize - 1) || 1482 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
1485 src->offset & (alignmask - 1) || 1483 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
1486 dst->length & (blocksize - 1) || 1484 offset) {
1487 dst->offset & (alignmask - 1) ||
1488 offset) {
1489 unsigned slen = src->length - offset; 1485 unsigned slen = src->length - offset;
1490 unsigned dlen = PAGE_SIZE; 1486 unsigned dlen = PAGE_SIZE;
1491 1487
@@ -1498,8 +1494,8 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1498 1494
1499 idx += err; 1495 idx += err;
1500 1496
1501 copy = slen & ~(blocksize - 1); 1497 copy = slen & ~(HIFN_D_DST_DALIGN - 1);
1502 diff = slen & (blocksize - 1); 1498 diff = slen & (HIFN_D_DST_DALIGN - 1);
1503 1499
1504 if (dlen < nbytes) { 1500 if (dlen < nbytes) {
1505 /* 1501 /*
@@ -1507,7 +1503,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1507 * to put there additional blocksized chunk, 1503 * to put there additional blocksized chunk,
1508 * so we mark that page as containing only 1504 * so we mark that page as containing only
1509 * blocksize aligned chunks: 1505 * blocksize aligned chunks:
1510 * t->length = (slen & ~(blocksize - 1)); 1506 * t->length = (slen & ~(HIFN_D_DST_DALIGN - 1));
1511 * and increase number of bytes to be processed 1507 * and increase number of bytes to be processed
1512 * in next chunk: 1508 * in next chunk:
1513 * nbytes += diff; 1509 * nbytes += diff;
@@ -1567,10 +1563,6 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1567 unsigned int nbytes = req->nbytes, idx = 0, len; 1563 unsigned int nbytes = req->nbytes, idx = 0, len;
1568 int err = -EINVAL, sg_num; 1564 int err = -EINVAL, sg_num;
1569 struct scatterlist *src, *dst, *t; 1565 struct scatterlist *src, *dst, *t;
1570 unsigned blocksize =
1571 crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(req));
1572 unsigned alignmask =
1573 crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req));
1574 1566
1575 if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB) 1567 if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB)
1576 goto err_out_exit; 1568 goto err_out_exit;
@@ -1578,17 +1570,13 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1578 ctx->walk.flags = 0; 1570 ctx->walk.flags = 0;
1579 1571
1580 while (nbytes) { 1572 while (nbytes) {
1581 src = &req->src[idx];
1582 dst = &req->dst[idx]; 1573 dst = &req->dst[idx];
1583 1574
1584 if (src->length & (blocksize - 1) || 1575 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
1585 src->offset & (alignmask - 1) || 1576 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN))
1586 dst->length & (blocksize - 1) ||
1587 dst->offset & (alignmask - 1)) {
1588 ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED; 1577 ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED;
1589 }
1590 1578
1591 nbytes -= src->length; 1579 nbytes -= dst->length;
1592 idx++; 1580 idx++;
1593 } 1581 }
1594 1582
@@ -2523,9 +2511,7 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t)
2523 alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; 2511 alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC;
2524 alg->alg.cra_blocksize = t->bsize; 2512 alg->alg.cra_blocksize = t->bsize;
2525 alg->alg.cra_ctxsize = sizeof(struct hifn_context); 2513 alg->alg.cra_ctxsize = sizeof(struct hifn_context);
2526 alg->alg.cra_alignmask = 15; 2514 alg->alg.cra_alignmask = 0;
2527 if (t->bsize == 8)
2528 alg->alg.cra_alignmask = 3;
2529 alg->alg.cra_type = &crypto_ablkcipher_type; 2515 alg->alg.cra_type = &crypto_ablkcipher_type;
2530 alg->alg.cra_module = THIS_MODULE; 2516 alg->alg.cra_module = THIS_MODULE;
2531 alg->alg.cra_u.ablkcipher = t->ablkcipher; 2517 alg->alg.cra_u.ablkcipher = t->ablkcipher;