Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Browse files Browse the repository at this point in the history
Pull another crypto fix from Herbert Xu:
 "Fix ICV corruption in s390/ghash when the same tfm is used by more
  than one thread"

* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: s390/ghash - Fix incorrect ghash icv buffer handling.
  • Loading branch information
Linus Torvalds committed May 22, 2015
2 parents 865d872 + a1cae34 commit 2a058f3
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions arch/s390/crypto/ghash_s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@
#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;
};

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;
}
Expand All @@ -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;
}
Expand All @@ -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;
Expand All @@ -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);
if (ret != GHASH_BLOCK_SIZE)
return -EIO;
Expand All @@ -79,7 +80,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);
if (ret != n)
return -EIO;
src += n;
Expand All @@ -94,7 +95,7 @@ static int ghash_update(struct shash_desc *desc,
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;
int ret;
Expand All @@ -104,24 +105,24 @@ static int 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);
if (ret != GHASH_BLOCK_SIZE)
return -EIO;

dctx->bytes = 0;
}

dctx->bytes = 0;
return 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);
int ret;

ret = ghash_flush(ctx, dctx);
ret = ghash_flush(dctx);
if (!ret)
memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE);
memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE);
return ret;
}

Expand Down

0 comments on commit 2a058f3

Please sign in to comment.