diff options
author | Horia Geantă <horia.geanta@nxp.com> | 2017-02-10 07:07:18 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-02-15 00:23:39 -0500 |
commit | fd144d83cc42cfe6c82cba76bc0113dacd53a4d4 (patch) | |
tree | 7d233ab0c8a743332ef4ac426611348ab43f755a | |
parent | fd88aac93e4dc7810940e854be1c3dc5adb20120 (diff) |
crypto: caam - check sg_count() return value
sg_count() internally calls sg_nents_for_len(), which could fail
in case the required number of bytes is larger than the total
bytes in the S/G.
Thus, add checks to validate the input.
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | drivers/crypto/caam/caamalg.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 05d4690351b9..ed8a04412767 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c | |||
@@ -1335,13 +1335,31 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, | |||
1335 | 1335 | ||
1336 | if (unlikely(req->dst != req->src)) { | 1336 | if (unlikely(req->dst != req->src)) { |
1337 | src_nents = sg_count(req->src, req->assoclen + req->cryptlen); | 1337 | src_nents = sg_count(req->src, req->assoclen + req->cryptlen); |
1338 | if (unlikely(src_nents < 0)) { | ||
1339 | dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n", | ||
1340 | req->assoclen + req->cryptlen); | ||
1341 | return ERR_PTR(src_nents); | ||
1342 | } | ||
1343 | |||
1338 | dst_nents = sg_count(req->dst, | 1344 | dst_nents = sg_count(req->dst, |
1339 | req->assoclen + req->cryptlen + | 1345 | req->assoclen + req->cryptlen + |
1340 | (encrypt ? authsize : (-authsize))); | 1346 | (encrypt ? authsize : (-authsize))); |
1347 | if (unlikely(dst_nents < 0)) { | ||
1348 | dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n", | ||
1349 | req->assoclen + req->cryptlen + | ||
1350 | (encrypt ? authsize : (-authsize))); | ||
1351 | return ERR_PTR(dst_nents); | ||
1352 | } | ||
1341 | } else { | 1353 | } else { |
1342 | src_nents = sg_count(req->src, | 1354 | src_nents = sg_count(req->src, |
1343 | req->assoclen + req->cryptlen + | 1355 | req->assoclen + req->cryptlen + |
1344 | (encrypt ? authsize : 0)); | 1356 | (encrypt ? authsize : 0)); |
1357 | if (unlikely(src_nents < 0)) { | ||
1358 | dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n", | ||
1359 | req->assoclen + req->cryptlen + | ||
1360 | (encrypt ? authsize : 0)); | ||
1361 | return ERR_PTR(src_nents); | ||
1362 | } | ||
1345 | } | 1363 | } |
1346 | 1364 | ||
1347 | /* Check if data are contiguous. */ | 1365 | /* Check if data are contiguous. */ |
@@ -1609,9 +1627,20 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request | |||
1609 | int sec4_sg_index; | 1627 | int sec4_sg_index; |
1610 | 1628 | ||
1611 | src_nents = sg_count(req->src, req->nbytes); | 1629 | src_nents = sg_count(req->src, req->nbytes); |
1630 | if (unlikely(src_nents < 0)) { | ||
1631 | dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n", | ||
1632 | req->nbytes); | ||
1633 | return ERR_PTR(src_nents); | ||
1634 | } | ||
1612 | 1635 | ||
1613 | if (req->dst != req->src) | 1636 | if (req->dst != req->src) { |
1614 | dst_nents = sg_count(req->dst, req->nbytes); | 1637 | dst_nents = sg_count(req->dst, req->nbytes); |
1638 | if (unlikely(dst_nents < 0)) { | ||
1639 | dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n", | ||
1640 | req->nbytes); | ||
1641 | return ERR_PTR(dst_nents); | ||
1642 | } | ||
1643 | } | ||
1615 | 1644 | ||
1616 | if (likely(req->src == req->dst)) { | 1645 | if (likely(req->src == req->dst)) { |
1617 | sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, | 1646 | sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, |
@@ -1807,6 +1836,11 @@ static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc( | |||
1807 | int sec4_sg_index; | 1836 | int sec4_sg_index; |
1808 | 1837 | ||
1809 | src_nents = sg_count(req->src, req->nbytes); | 1838 | src_nents = sg_count(req->src, req->nbytes); |
1839 | if (unlikely(src_nents < 0)) { | ||
1840 | dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n", | ||
1841 | req->nbytes); | ||
1842 | return ERR_PTR(src_nents); | ||
1843 | } | ||
1810 | 1844 | ||
1811 | if (likely(req->src == req->dst)) { | 1845 | if (likely(req->src == req->dst)) { |
1812 | sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, | 1846 | sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, |
@@ -1826,6 +1860,12 @@ static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc( | |||
1826 | } | 1860 | } |
1827 | 1861 | ||
1828 | dst_nents = sg_count(req->dst, req->nbytes); | 1862 | dst_nents = sg_count(req->dst, req->nbytes); |
1863 | if (unlikely(dst_nents < 0)) { | ||
1864 | dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n", | ||
1865 | req->nbytes); | ||
1866 | return ERR_PTR(dst_nents); | ||
1867 | } | ||
1868 | |||
1829 | sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1, | 1869 | sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1, |
1830 | DMA_FROM_DEVICE); | 1870 | DMA_FROM_DEVICE); |
1831 | if (unlikely(!sgc)) { | 1871 | if (unlikely(!sgc)) { |
@@ -1914,7 +1954,7 @@ static int ablkcipher_givencrypt(struct skcipher_givcrypt_request *creq) | |||
1914 | struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); | 1954 | struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); |
1915 | struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); | 1955 | struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); |
1916 | struct device *jrdev = ctx->jrdev; | 1956 | struct device *jrdev = ctx->jrdev; |
1917 | bool iv_contig; | 1957 | bool iv_contig = false; |
1918 | u32 *desc; | 1958 | u32 *desc; |
1919 | int ret = 0; | 1959 | int ret = 0; |
1920 | 1960 | ||