Commit 08878d1c authored by Harald Freudenberger's avatar Harald Freudenberger Committed by Zefan Li

crypto: s390/ghash - Fix incorrect ghash icv buffer handling.

commit a1cae34e upstream.

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.
Signed-off-by: default avatarHarald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: default avatarGerald Schaefer <geraldsc@linux.vnet.ibm.com>
Reported-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
[lizf: Backported to 3.4:
 - adjust context
 - drop the change to memcpy()]
Signed-off-by: default avatarZefan Li <lizefan@huawei.com>
parent 0b80fa4b
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
#define GHASH_DIGEST_SIZE 16 #define GHASH_DIGEST_SIZE 16
struct ghash_ctx { struct ghash_ctx {
u8 icv[16]; u8 key[GHASH_BLOCK_SIZE];
u8 key[16];
}; };
struct ghash_desc_ctx { struct ghash_desc_ctx {
u8 icv[GHASH_BLOCK_SIZE];
u8 key[GHASH_BLOCK_SIZE];
u8 buffer[GHASH_BLOCK_SIZE]; u8 buffer[GHASH_BLOCK_SIZE];
u32 bytes; u32 bytes;
}; };
...@@ -28,8 +29,10 @@ struct ghash_desc_ctx { ...@@ -28,8 +29,10 @@ struct ghash_desc_ctx {
static int ghash_init(struct shash_desc *desc) static int ghash_init(struct shash_desc *desc)
{ {
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
memset(dctx, 0, sizeof(*dctx)); memset(dctx, 0, sizeof(*dctx));
memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE);
return 0; return 0;
} }
...@@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_shash *tfm, ...@@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_shash *tfm,
} }
memcpy(ctx->key, key, GHASH_BLOCK_SIZE); memcpy(ctx->key, key, GHASH_BLOCK_SIZE);
memset(ctx->icv, 0, GHASH_BLOCK_SIZE);
return 0; return 0;
} }
...@@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc, ...@@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc,
const u8 *src, unsigned int srclen) const u8 *src, unsigned int srclen)
{ {
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
unsigned int n; unsigned int n;
u8 *buf = dctx->buffer; u8 *buf = dctx->buffer;
int ret; int ret;
...@@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc, ...@@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc,
src += n; src += n;
if (!dctx->bytes) { if (!dctx->bytes) {
ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf,
GHASH_BLOCK_SIZE); GHASH_BLOCK_SIZE);
BUG_ON(ret != GHASH_BLOCK_SIZE); BUG_ON(ret != GHASH_BLOCK_SIZE);
} }
...@@ -78,7 +79,7 @@ static int ghash_update(struct shash_desc *desc, ...@@ -78,7 +79,7 @@ static int ghash_update(struct shash_desc *desc,
n = srclen & ~(GHASH_BLOCK_SIZE - 1); n = srclen & ~(GHASH_BLOCK_SIZE - 1);
if (n) { if (n) {
ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n);
BUG_ON(ret != n); BUG_ON(ret != n);
src += n; src += n;
srclen -= n; srclen -= n;
...@@ -92,7 +93,7 @@ static int ghash_update(struct shash_desc *desc, ...@@ -92,7 +93,7 @@ static int ghash_update(struct shash_desc *desc,
return 0; return 0;
} }
static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) static int ghash_flush(struct ghash_desc_ctx *dctx)
{ {
u8 *buf = dctx->buffer; u8 *buf = dctx->buffer;
int ret; int ret;
...@@ -102,20 +103,19 @@ static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) ...@@ -102,20 +103,19 @@ static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
memset(pos, 0, dctx->bytes); memset(pos, 0, dctx->bytes);
ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE); ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE);
BUG_ON(ret != GHASH_BLOCK_SIZE); BUG_ON(ret != GHASH_BLOCK_SIZE);
}
dctx->bytes = 0; dctx->bytes = 0;
}
} }
static int ghash_final(struct shash_desc *desc, u8 *dst) static int ghash_final(struct shash_desc *desc, u8 *dst)
{ {
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
ghash_flush(ctx, dctx); ghash_flush(dctx);
memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); memcpy(dst, dtx->icv, GHASH_BLOCK_SIZE);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment