diff options
Diffstat (limited to 'drivers/crypto/talitos.c')
-rw-r--r-- | drivers/crypto/talitos.c | 77 |
1 files changed, 40 insertions, 37 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index bd78acf3c365..97f4af1d8a64 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
@@ -720,7 +720,6 @@ struct talitos_ctx { | |||
720 | #define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512 | 720 | #define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512 |
721 | 721 | ||
722 | struct talitos_ahash_req_ctx { | 722 | struct talitos_ahash_req_ctx { |
723 | u64 count; | ||
724 | u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; | 723 | u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; |
725 | unsigned int hw_context_size; | 724 | unsigned int hw_context_size; |
726 | u8 buf[HASH_MAX_BLOCK_SIZE]; | 725 | u8 buf[HASH_MAX_BLOCK_SIZE]; |
@@ -729,6 +728,7 @@ struct talitos_ahash_req_ctx { | |||
729 | unsigned int first; | 728 | unsigned int first; |
730 | unsigned int last; | 729 | unsigned int last; |
731 | unsigned int to_hash_later; | 730 | unsigned int to_hash_later; |
731 | u64 nbuf; | ||
732 | struct scatterlist bufsl[2]; | 732 | struct scatterlist bufsl[2]; |
733 | struct scatterlist *psrc; | 733 | struct scatterlist *psrc; |
734 | }; | 734 | }; |
@@ -1613,6 +1613,7 @@ static void ahash_done(struct device *dev, | |||
1613 | if (!req_ctx->last && req_ctx->to_hash_later) { | 1613 | if (!req_ctx->last && req_ctx->to_hash_later) { |
1614 | /* Position any partial block for next update/final/finup */ | 1614 | /* Position any partial block for next update/final/finup */ |
1615 | memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later); | 1615 | memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later); |
1616 | req_ctx->nbuf = req_ctx->to_hash_later; | ||
1616 | } | 1617 | } |
1617 | common_nonsnoop_hash_unmap(dev, edesc, areq); | 1618 | common_nonsnoop_hash_unmap(dev, edesc, areq); |
1618 | 1619 | ||
@@ -1728,7 +1729,7 @@ static int ahash_init(struct ahash_request *areq) | |||
1728 | struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); | 1729 | struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); |
1729 | 1730 | ||
1730 | /* Initialize the context */ | 1731 | /* Initialize the context */ |
1731 | req_ctx->count = 0; | 1732 | req_ctx->nbuf = 0; |
1732 | req_ctx->first = 1; /* first indicates h/w must init its context */ | 1733 | req_ctx->first = 1; /* first indicates h/w must init its context */ |
1733 | req_ctx->swinit = 0; /* assume h/w init of context */ | 1734 | req_ctx->swinit = 0; /* assume h/w init of context */ |
1734 | req_ctx->hw_context_size = | 1735 | req_ctx->hw_context_size = |
@@ -1776,52 +1777,54 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes) | |||
1776 | crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); | 1777 | crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); |
1777 | unsigned int nbytes_to_hash; | 1778 | unsigned int nbytes_to_hash; |
1778 | unsigned int to_hash_later; | 1779 | unsigned int to_hash_later; |
1779 | unsigned int index; | 1780 | unsigned int nsg; |
1780 | int chained; | 1781 | int chained; |
1781 | 1782 | ||
1782 | index = req_ctx->count & (blocksize - 1); | 1783 | if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) { |
1783 | req_ctx->count += nbytes; | 1784 | /* Buffer up to one whole block */ |
1784 | |||
1785 | if (!req_ctx->last && (index + nbytes) < blocksize) { | ||
1786 | /* Buffer the partial block */ | ||
1787 | sg_copy_to_buffer(areq->src, | 1785 | sg_copy_to_buffer(areq->src, |
1788 | sg_count(areq->src, nbytes, &chained), | 1786 | sg_count(areq->src, nbytes, &chained), |
1789 | req_ctx->buf + index, nbytes); | 1787 | req_ctx->buf + req_ctx->nbuf, nbytes); |
1788 | req_ctx->nbuf += nbytes; | ||
1790 | return 0; | 1789 | return 0; |
1791 | } | 1790 | } |
1792 | 1791 | ||
1793 | if (index) { | 1792 | /* At least (blocksize + 1) bytes are available to hash */ |
1794 | /* partial block from previous update; chain it in. */ | 1793 | nbytes_to_hash = nbytes + req_ctx->nbuf; |
1795 | sg_init_table(req_ctx->bufsl, (nbytes) ? 2 : 1); | 1794 | to_hash_later = nbytes_to_hash & (blocksize - 1); |
1796 | sg_set_buf(req_ctx->bufsl, req_ctx->buf, index); | 1795 | |
1797 | if (nbytes) | 1796 | if (req_ctx->last) |
1798 | scatterwalk_sg_chain(req_ctx->bufsl, 2, | 1797 | to_hash_later = 0; |
1799 | areq->src); | 1798 | else if (to_hash_later) |
1799 | /* There is a partial block. Hash the full block(s) now */ | ||
1800 | nbytes_to_hash -= to_hash_later; | ||
1801 | else { | ||
1802 | /* Keep one block buffered */ | ||
1803 | nbytes_to_hash -= blocksize; | ||
1804 | to_hash_later = blocksize; | ||
1805 | } | ||
1806 | |||
1807 | /* Chain in any previously buffered data */ | ||
1808 | if (req_ctx->nbuf) { | ||
1809 | nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1; | ||
1810 | sg_init_table(req_ctx->bufsl, nsg); | ||
1811 | sg_set_buf(req_ctx->bufsl, req_ctx->buf, req_ctx->nbuf); | ||
1812 | if (nsg > 1) | ||
1813 | scatterwalk_sg_chain(req_ctx->bufsl, 2, areq->src); | ||
1800 | req_ctx->psrc = req_ctx->bufsl; | 1814 | req_ctx->psrc = req_ctx->bufsl; |
1801 | } else { | 1815 | } else |
1802 | req_ctx->psrc = areq->src; | 1816 | req_ctx->psrc = areq->src; |
1817 | |||
1818 | if (to_hash_later) { | ||
1819 | int nents = sg_count(areq->src, nbytes, &chained); | ||
1820 | sg_copy_end_to_buffer(areq->src, nents, | ||
1821 | req_ctx->bufnext, | ||
1822 | to_hash_later, | ||
1823 | nbytes - to_hash_later); | ||
1803 | } | 1824 | } |
1804 | nbytes_to_hash = index + nbytes; | 1825 | req_ctx->to_hash_later = to_hash_later; |
1805 | if (!req_ctx->last) { | ||
1806 | to_hash_later = (nbytes_to_hash & (blocksize - 1)); | ||
1807 | if (to_hash_later) { | ||
1808 | int nents; | ||
1809 | /* Must copy to_hash_later bytes from the end | ||
1810 | * to bufnext (a partial block) for later. | ||
1811 | */ | ||
1812 | nents = sg_count(areq->src, nbytes, &chained); | ||
1813 | sg_copy_end_to_buffer(areq->src, nents, | ||
1814 | req_ctx->bufnext, | ||
1815 | to_hash_later, | ||
1816 | nbytes - to_hash_later); | ||
1817 | |||
1818 | /* Adjust count for what will be hashed now */ | ||
1819 | nbytes_to_hash -= to_hash_later; | ||
1820 | } | ||
1821 | req_ctx->to_hash_later = to_hash_later; | ||
1822 | } | ||
1823 | 1826 | ||
1824 | /* allocate extended descriptor */ | 1827 | /* Allocate extended descriptor */ |
1825 | edesc = ahash_edesc_alloc(areq, nbytes_to_hash); | 1828 | edesc = ahash_edesc_alloc(areq, nbytes_to_hash); |
1826 | if (IS_ERR(edesc)) | 1829 | if (IS_ERR(edesc)) |
1827 | return PTR_ERR(edesc); | 1830 | return PTR_ERR(edesc); |