aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Freudenberger <freude@linux.vnet.ibm.com>2015-05-21 04:01:11 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-05-21 23:23:03 -0400
commita1cae34e23b1293eccbcc8ee9b39298039c3952a (patch)
treee1d43c2c40d8bb1ce1ee2322acce92ff12fb54c0
parent7b2a18e05feb86f9be25602abfa9604a6b977f79 (diff)
crypto: s390/ghash - Fix incorrect ghash icv buffer handling.
Multitheaded tests showed that the icv buffer in the current ghash implementation is not handled correctly. A move of this working ghash buffer value to the descriptor context fixed this. Code is tested and verified with an multithreaded application via af_alg interface. Cc: stable@vger.kernel.org Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com> Signed-off-by: Gerald Schaefer <geraldsc@linux.vnet.ibm.com> Reported-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--arch/s390/crypto/ghash_s390.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/arch/s390/crypto/ghash_s390.c b/arch/s390/crypto/ghash_s390.c
index 7940dc90e80b..b258110da952 100644
--- a/arch/s390/crypto/ghash_s390.c
+++ b/arch/s390/crypto/ghash_s390.c
@@ -16,11 +16,12 @@
16#define GHASH_DIGEST_SIZE 16 16#define GHASH_DIGEST_SIZE 16
17 17
18struct ghash_ctx { 18struct ghash_ctx {
19 u8 icv[16]; 19 u8 key[GHASH_BLOCK_SIZE];
20 u8 key[16];
21}; 20};
22 21
23struct ghash_desc_ctx { 22struct ghash_desc_ctx {
23 u8 icv[GHASH_BLOCK_SIZE];
24 u8 key[GHASH_BLOCK_SIZE];
24 u8 buffer[GHASH_BLOCK_SIZE]; 25 u8 buffer[GHASH_BLOCK_SIZE];
25 u32 bytes; 26 u32 bytes;
26}; 27};
@@ -28,8 +29,10 @@ struct ghash_desc_ctx {
28static int ghash_init(struct shash_desc *desc) 29static int ghash_init(struct shash_desc *desc)
29{ 30{
30 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); 31 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
32 struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
31 33
32 memset(dctx, 0, sizeof(*dctx)); 34 memset(dctx, 0, sizeof(*dctx));
35 memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE);
33 36
34 return 0; 37 return 0;
35} 38}
@@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_shash *tfm,
45 } 48 }
46 49
47 memcpy(ctx->key, key, GHASH_BLOCK_SIZE); 50 memcpy(ctx->key, key, GHASH_BLOCK_SIZE);
48 memset(ctx->icv, 0, GHASH_BLOCK_SIZE);
49 51
50 return 0; 52 return 0;
51} 53}
@@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc,
54 const u8 *src, unsigned int srclen) 56 const u8 *src, unsigned int srclen)
55{ 57{
56 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); 58 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
57 struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
58 unsigned int n; 59 unsigned int n;
59 u8 *buf = dctx->buffer; 60 u8 *buf = dctx->buffer;
60 int ret; 61 int ret;
@@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc,
70 src += n; 71 src += n;
71 72
72 if (!dctx->bytes) { 73 if (!dctx->bytes) {
73 ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, 74 ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf,
74 GHASH_BLOCK_SIZE); 75 GHASH_BLOCK_SIZE);
75 if (ret != GHASH_BLOCK_SIZE) 76 if (ret != GHASH_BLOCK_SIZE)
76 return -EIO; 77 return -EIO;
@@ -79,7 +80,7 @@ static int ghash_update(struct shash_desc *desc,
79 80
80 n = srclen & ~(GHASH_BLOCK_SIZE - 1); 81 n = srclen & ~(GHASH_BLOCK_SIZE - 1);
81 if (n) { 82 if (n) {
82 ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); 83 ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n);
83 if (ret != n) 84 if (ret != n)
84 return -EIO; 85 return -EIO;
85 src += n; 86 src += n;
@@ -94,7 +95,7 @@ static int ghash_update(struct shash_desc *desc,
94 return 0; 95 return 0;
95} 96}
96 97
97static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) 98static int ghash_flush(struct ghash_desc_ctx *dctx)
98{ 99{
99 u8 *buf = dctx->buffer; 100 u8 *buf = dctx->buffer;
100 int ret; 101 int ret;
@@ -104,24 +105,24 @@ static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
104 105
105 memset(pos, 0, dctx->bytes); 106 memset(pos, 0, dctx->bytes);
106 107
107 ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE); 108 ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE);
108 if (ret != GHASH_BLOCK_SIZE) 109 if (ret != GHASH_BLOCK_SIZE)
109 return -EIO; 110 return -EIO;
111
112 dctx->bytes = 0;
110 } 113 }
111 114
112 dctx->bytes = 0;
113 return 0; 115 return 0;
114} 116}
115 117
116static int ghash_final(struct shash_desc *desc, u8 *dst) 118static int ghash_final(struct shash_desc *desc, u8 *dst)
117{ 119{
118 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); 120 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
119 struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
120 int ret; 121 int ret;
121 122
122 ret = ghash_flush(ctx, dctx); 123 ret = ghash_flush(dctx);
123 if (!ret) 124 if (!ret)
124 memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); 125 memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE);
125 return ret; 126 return ret;
126} 127}
127 128