diff options
author | Harald Freudenberger <freude@linux.vnet.ibm.com> | 2015-05-21 11:01:11 +0300 |
---|---|---|
committer | Zefan Li <lizefan@huawei.com> | 2015-09-18 04:20:42 +0300 |
commit | 08878d1cc1d2f80074dcb5452557ae34c771ac85 (patch) | |
tree | 5cccb734a3802a4a94e72998049d8a2e1319a526 | |
parent | 0b80fa4b24f50a87c796970661e45d6edc524a08 (diff) | |
download | linux-08878d1cc1d2f80074dcb5452557ae34c771ac85.tar.xz |
crypto: s390/ghash - Fix incorrect ghash icv buffer handling.
commit a1cae34e23b1293eccbcc8ee9b39298039c3952a 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: 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>
[lizf: Backported to 3.4:
- adjust context
- drop the change to memcpy()]
Signed-off-by: Zefan Li <lizefan@huawei.com>
-rw-r--r-- | arch/s390/crypto/ghash_s390.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/arch/s390/crypto/ghash_s390.c b/arch/s390/crypto/ghash_s390.c index b1bd170f24b1..c2dac2e0e56a 100644 --- a/arch/s390/crypto/ghash_s390.c +++ b/arch/s390/crypto/ghash_s390.c @@ -16,11 +16,12 @@ #define GHASH_DIGEST_SIZE 16 struct ghash_ctx { - u8 icv[16]; - u8 key[16]; + u8 key[GHASH_BLOCK_SIZE]; }; struct ghash_desc_ctx { + u8 icv[GHASH_BLOCK_SIZE]; + u8 key[GHASH_BLOCK_SIZE]; u8 buffer[GHASH_BLOCK_SIZE]; u32 bytes; }; @@ -28,8 +29,10 @@ struct ghash_desc_ctx { static int ghash_init(struct shash_desc *desc) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); + struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); memset(dctx, 0, sizeof(*dctx)); + memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE); return 0; } @@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_shash *tfm, } memcpy(ctx->key, key, GHASH_BLOCK_SIZE); - memset(ctx->icv, 0, GHASH_BLOCK_SIZE); return 0; } @@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc, const u8 *src, unsigned int srclen) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); unsigned int n; u8 *buf = dctx->buffer; int ret; @@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc, src += n; if (!dctx->bytes) { - ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, + ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE); BUG_ON(ret != GHASH_BLOCK_SIZE); } @@ -78,7 +79,7 @@ static int ghash_update(struct shash_desc *desc, n = srclen & ~(GHASH_BLOCK_SIZE - 1); if (n) { - ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); + ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n); BUG_ON(ret != n); src += n; srclen -= n; @@ -92,7 +93,7 @@ static int ghash_update(struct shash_desc *desc, 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; int ret; @@ -102,20 +103,19 @@ static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) 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); - } - dctx->bytes = 0; + dctx->bytes = 0; + } } static int ghash_final(struct shash_desc *desc, u8 *dst) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); - ghash_flush(ctx, dctx); - memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); + ghash_flush(dctx); + memcpy(dst, dtx->icv, GHASH_BLOCK_SIZE); return 0; } |