mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 08:31:13 +00:00
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>
This commit is contained in:
parent
7b2a18e05f
commit
a1cae34e23
1 changed files with 13 additions and 12 deletions
|
@ -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 {
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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);
|
||||||
if (ret != GHASH_BLOCK_SIZE)
|
if (ret != GHASH_BLOCK_SIZE)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -79,7 +80,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);
|
||||||
if (ret != n)
|
if (ret != n)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
src += n;
|
src += n;
|
||||||
|
@ -94,7 +95,7 @@ static int ghash_update(struct shash_desc *desc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int 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;
|
||||||
|
@ -104,24 +105,24 @@ static int 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);
|
||||||
if (ret != GHASH_BLOCK_SIZE)
|
if (ret != GHASH_BLOCK_SIZE)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
|
dctx->bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dctx->bytes = 0;
|
|
||||||
return 0;
|
return 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);
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = ghash_flush(ctx, dctx);
|
ret = ghash_flush(dctx);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE);
|
memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue