History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

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.

Linus Torvalds committed 11 years ago

Commit 2a058f32 parents 865d872 a1cae341 file · +13 −12Browse files

Unified · Split

arch/s390/crypto/ghash_s390.c+13−12
@@ -16,11 +16,12 @@ · 15 unmodified lines
16#define GHASH_DIGEST_SIZE 1616#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 { · 1 unmodified line
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, · 9 unmodified lines
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, · 2 unmodified lines
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, · 9 unmodified lines
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, · 2 unmodified lines
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, · 8 unmodified lines
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) · 3 unmodified lines
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