]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.17/crypto-inside-secure-fix-hash-when-length-is-a-multiple-of-a-block.patch
Linux 4.9.80
[thirdparty/kernel/stable-queue.git] / releases / 4.14.17 / crypto-inside-secure-fix-hash-when-length-is-a-multiple-of-a-block.patch
1 From 809778e02cd45d0625439fee67688f655627bb3c Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart@free-electrons.com>
3 Date: Tue, 26 Dec 2017 17:21:17 +0100
4 Subject: crypto: inside-secure - fix hash when length is a multiple of a block
5
6 From: Antoine Tenart <antoine.tenart@free-electrons.com>
7
8 commit 809778e02cd45d0625439fee67688f655627bb3c upstream.
9
10 This patch fixes the hash support in the SafeXcel driver when the update
11 size is a multiple of a block size, and when a final call is made just
12 after with a size of 0. In such cases the driver should cache the last
13 block from the update to avoid handling 0 length data on the final call
14 (that's a hardware limitation).
15
16 Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
17 Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
18 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
19 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20
21 ---
22 drivers/crypto/inside-secure/safexcel_hash.c | 34 +++++++++++++++++++--------
23 1 file changed, 24 insertions(+), 10 deletions(-)
24
25 --- a/drivers/crypto/inside-secure/safexcel_hash.c
26 +++ b/drivers/crypto/inside-secure/safexcel_hash.c
27 @@ -185,17 +185,31 @@ static int safexcel_ahash_send(struct cr
28 else
29 cache_len = queued - areq->nbytes;
30
31 - /*
32 - * If this is not the last request and the queued data does not fit
33 - * into full blocks, cache it for the next send() call.
34 - */
35 - extra = queued & (crypto_ahash_blocksize(ahash) - 1);
36 - if (!req->last_req && extra) {
37 - sg_pcopy_to_buffer(areq->src, sg_nents(areq->src),
38 - req->cache_next, extra, areq->nbytes - extra);
39 + if (!req->last_req) {
40 + /* If this is not the last request and the queued data does not
41 + * fit into full blocks, cache it for the next send() call.
42 + */
43 + extra = queued & (crypto_ahash_blocksize(ahash) - 1);
44 + if (!extra)
45 + /* If this is not the last request and the queued data
46 + * is a multiple of a block, cache the last one for now.
47 + */
48 + extra = queued - crypto_ahash_blocksize(ahash);
49
50 - queued -= extra;
51 - len -= extra;
52 + if (extra) {
53 + sg_pcopy_to_buffer(areq->src, sg_nents(areq->src),
54 + req->cache_next, extra,
55 + areq->nbytes - extra);
56 +
57 + queued -= extra;
58 + len -= extra;
59 +
60 + if (!queued) {
61 + *commands = 0;
62 + *results = 0;
63 + return 0;
64 + }
65 + }
66 }
67
68 spin_lock_bh(&priv->ring[ring].egress_lock);