]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.14.44/crypto-s390-ghash-fix-incorrect-ghash-icv-buffer-handling.patch
drop queue-4.14/mips-make-sure-dt-memory-regions-are-valid.patch
[thirdparty/kernel/stable-queue.git] / releases / 3.14.44 / crypto-s390-ghash-fix-incorrect-ghash-icv-buffer-handling.patch
1 From a1cae34e23b1293eccbcc8ee9b39298039c3952a Mon Sep 17 00:00:00 2001
2 From: Harald Freudenberger <freude@linux.vnet.ibm.com>
3 Date: Thu, 21 May 2015 10:01:11 +0200
4 Subject: crypto: s390/ghash - Fix incorrect ghash icv buffer handling.
5
6 From: Harald Freudenberger <freude@linux.vnet.ibm.com>
7
8 commit a1cae34e23b1293eccbcc8ee9b39298039c3952a upstream.
9
10 Multitheaded tests showed that the icv buffer in the current ghash
11 implementation is not handled correctly. A move of this working ghash
12 buffer value to the descriptor context fixed this. Code is tested and
13 verified with an multithreaded application via af_alg interface.
14
15 Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
16 Signed-off-by: Gerald Schaefer <geraldsc@linux.vnet.ibm.com>
17 Reported-by: Herbert Xu <herbert@gondor.apana.org.au>
18 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
19 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20
21 ---
22 arch/s390/crypto/ghash_s390.c | 25 +++++++++++++------------
23 1 file changed, 13 insertions(+), 12 deletions(-)
24
25 --- a/arch/s390/crypto/ghash_s390.c
26 +++ b/arch/s390/crypto/ghash_s390.c
27 @@ -16,11 +16,12 @@
28 #define GHASH_DIGEST_SIZE 16
29
30 struct ghash_ctx {
31 - u8 icv[16];
32 - u8 key[16];
33 + u8 key[GHASH_BLOCK_SIZE];
34 };
35
36 struct ghash_desc_ctx {
37 + u8 icv[GHASH_BLOCK_SIZE];
38 + u8 key[GHASH_BLOCK_SIZE];
39 u8 buffer[GHASH_BLOCK_SIZE];
40 u32 bytes;
41 };
42 @@ -28,8 +29,10 @@ struct ghash_desc_ctx {
43 static int ghash_init(struct shash_desc *desc)
44 {
45 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
46 + struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
47
48 memset(dctx, 0, sizeof(*dctx));
49 + memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE);
50
51 return 0;
52 }
53 @@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_sh
54 }
55
56 memcpy(ctx->key, key, GHASH_BLOCK_SIZE);
57 - memset(ctx->icv, 0, GHASH_BLOCK_SIZE);
58
59 return 0;
60 }
61 @@ -54,7 +56,6 @@ static int ghash_update(struct shash_des
62 const u8 *src, unsigned int srclen)
63 {
64 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
65 - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
66 unsigned int n;
67 u8 *buf = dctx->buffer;
68 int ret;
69 @@ -70,7 +71,7 @@ static int ghash_update(struct shash_des
70 src += n;
71
72 if (!dctx->bytes) {
73 - ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf,
74 + ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf,
75 GHASH_BLOCK_SIZE);
76 if (ret != GHASH_BLOCK_SIZE)
77 return -EIO;
78 @@ -79,7 +80,7 @@ static int ghash_update(struct shash_des
79
80 n = srclen & ~(GHASH_BLOCK_SIZE - 1);
81 if (n) {
82 - ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n);
83 + ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n);
84 if (ret != n)
85 return -EIO;
86 src += n;
87 @@ -94,7 +95,7 @@ static int ghash_update(struct shash_des
88 return 0;
89 }
90
91 -static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
92 +static int ghash_flush(struct ghash_desc_ctx *dctx)
93 {
94 u8 *buf = dctx->buffer;
95 int ret;
96 @@ -104,24 +105,24 @@ static int ghash_flush(struct ghash_ctx
97
98 memset(pos, 0, dctx->bytes);
99
100 - ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE);
101 + ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE);
102 if (ret != GHASH_BLOCK_SIZE)
103 return -EIO;
104 +
105 + dctx->bytes = 0;
106 }
107
108 - dctx->bytes = 0;
109 return 0;
110 }
111
112 static int ghash_final(struct shash_desc *desc, u8 *dst)
113 {
114 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
115 - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
116 int ret;
117
118 - ret = ghash_flush(ctx, dctx);
119 + ret = ghash_flush(dctx);
120 if (!ret)
121 - memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE);
122 + memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE);
123 return ret;
124 }
125