aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-05-07 10:34:27 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-07-10 08:35:11 -0400
commit136f702f51a4bfa38003660768e7153823fff8a1 (patch)
tree61bd60f542dcaf74419d47a7d5866138727bb566 /drivers/crypto
parentd069033b42b392662320f71e319296a14d57ff3a (diff)
[HIFN]: Properly handle requests for less than the full scatterlist
The scatterlist may contain more data than the crypto request, causing an underflow of the remaining byte count while walking the list. Use the minimum of the scatterlist element size and the remaining byte count specified in the crypto request to avoid this. Signed-off-by: Patrick McHardy <kaber@trash.net> Acked-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/hifn_795x.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 4428e8e68a0d..366e974d0e59 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1433,7 +1433,7 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist
1433 return -EINVAL; 1433 return -EINVAL;
1434 1434
1435 while (size) { 1435 while (size) {
1436 copy = min(drest, src->length); 1436 copy = min(drest, min(size, src->length));
1437 1437
1438 saddr = kmap_atomic(sg_page(src), KM_SOFTIRQ1); 1438 saddr = kmap_atomic(sg_page(src), KM_SOFTIRQ1);
1439 memcpy(daddr, saddr + src->offset, copy); 1439 memcpy(daddr, saddr + src->offset, copy);
@@ -1482,7 +1482,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1482 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || 1482 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
1483 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) || 1483 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
1484 offset) { 1484 offset) {
1485 unsigned slen = src->length - offset; 1485 unsigned slen = min(src->length - offset, nbytes);
1486 unsigned dlen = PAGE_SIZE; 1486 unsigned dlen = PAGE_SIZE;
1487 1487
1488 t = &w->cache[idx]; 1488 t = &w->cache[idx];
@@ -1540,7 +1540,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1540 1540
1541 kunmap_atomic(daddr, KM_SOFTIRQ0); 1541 kunmap_atomic(daddr, KM_SOFTIRQ0);
1542 } else { 1542 } else {
1543 nbytes -= src->length; 1543 nbytes -= min(src->length, nbytes);
1544 idx++; 1544 idx++;
1545 } 1545 }
1546 1546
@@ -1559,7 +1559,7 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1559 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); 1559 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
1560 struct hifn_device *dev = ctx->dev; 1560 struct hifn_device *dev = ctx->dev;
1561 struct page *spage, *dpage; 1561 struct page *spage, *dpage;
1562 unsigned long soff, doff, flags; 1562 unsigned long soff, doff, dlen, flags;
1563 unsigned int nbytes = req->nbytes, idx = 0, len; 1563 unsigned int nbytes = req->nbytes, idx = 0, len;
1564 int err = -EINVAL, sg_num; 1564 int err = -EINVAL, sg_num;
1565 struct scatterlist *src, *dst, *t; 1565 struct scatterlist *src, *dst, *t;
@@ -1571,12 +1571,13 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1571 1571
1572 while (nbytes) { 1572 while (nbytes) {
1573 dst = &req->dst[idx]; 1573 dst = &req->dst[idx];
1574 dlen = min(dst->length, nbytes);
1574 1575
1575 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || 1576 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
1576 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN)) 1577 !IS_ALIGNED(dlen, HIFN_D_DST_DALIGN))
1577 ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED; 1578 ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED;
1578 1579
1579 nbytes -= dst->length; 1580 nbytes -= dlen;
1580 idx++; 1581 idx++;
1581 } 1582 }
1582 1583
@@ -1631,7 +1632,7 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1631 if (err) 1632 if (err)
1632 goto err_out; 1633 goto err_out;
1633 1634
1634 nbytes -= len; 1635 nbytes -= min(len, nbytes);
1635 } 1636 }
1636 1637
1637 dev->active = HIFN_DEFAULT_ACTIVE_NUM; 1638 dev->active = HIFN_DEFAULT_ACTIVE_NUM;
@@ -1736,8 +1737,7 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset
1736 return -EINVAL; 1737 return -EINVAL;
1737 1738
1738 while (size) { 1739 while (size) {
1739 1740 copy = min(srest, min(dst->length, size));
1740 copy = min(dst->length, srest);
1741 1741
1742 daddr = kmap_atomic(sg_page(dst), KM_IRQ0); 1742 daddr = kmap_atomic(sg_page(dst), KM_IRQ0);
1743 memcpy(daddr + dst->offset + offset, saddr, copy); 1743 memcpy(daddr + dst->offset + offset, saddr, copy);
@@ -1794,7 +1794,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
1794 sg_page(dst), dst->length, nbytes); 1794 sg_page(dst), dst->length, nbytes);
1795 1795
1796 if (!t->length) { 1796 if (!t->length) {
1797 nbytes -= dst->length; 1797 nbytes -= min(dst->length, nbytes);
1798 idx++; 1798 idx++;
1799 continue; 1799 continue;
1800 } 1800 }