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.
Unified · Split
| @@ -16,11 +16,12 @@ · 15 unmodified lines | ||
| 16 | 16 | #define GHASH_DIGEST_SIZE 16 |
| 17 | 17 | |
| 18 | 18 | struct ghash_ctx { |
| 19 | − u8 icv[16]; | |
| 20 | − u8 key[16]; | |
| 19 | + u8 key[GHASH_BLOCK_SIZE]; | |
| 21 | 20 | }; |
| 22 | 21 | |
| 23 | 22 | struct ghash_desc_ctx { |
| 23 | + u8 icv[GHASH_BLOCK_SIZE]; | |
| 24 | + u8 key[GHASH_BLOCK_SIZE]; | |
| 24 | 25 | u8 buffer[GHASH_BLOCK_SIZE]; |
| 25 | 26 | u32 bytes; |
| 26 | 27 | }; |
| @@ -28,8 +29,10 @@ struct ghash_desc_ctx { · 1 unmodified line | ||
| 28 | 29 | static int ghash_init(struct shash_desc *desc) |
| 29 | 30 | { |
| 30 | 31 | struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); |
| 32 | + struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); | |
| 31 | 33 | |
| 32 | 34 | memset(dctx, 0, sizeof(*dctx)); |
| 35 | + memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE); | |
| 33 | 36 | |
| 34 | 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 | 50 | memcpy(ctx->key, key, GHASH_BLOCK_SIZE); |
| 48 | − memset(ctx->icv, 0, GHASH_BLOCK_SIZE); | |
| 49 | 51 | |
| 50 | 52 | return 0; |
| 51 | 53 | } |
| @@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc, · 2 unmodified lines | ||
| 54 | 56 | const u8 *src, unsigned int srclen) |
| 55 | 57 | { |
| 56 | 58 | struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); |
| 57 | − struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); | |
| 58 | 59 | unsigned int n; |
| 59 | 60 | u8 *buf = dctx->buffer; |
| 60 | 61 | int ret; |
| @@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc, · 9 unmodified lines | ||
| 70 | 71 | src += n; |
| 71 | 72 | |
| 72 | 73 | if (!dctx->bytes) { |
| 73 | − ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, | |
| 74 | + ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, | |
| 74 | 75 | GHASH_BLOCK_SIZE); |
| 75 | 76 | if (ret != GHASH_BLOCK_SIZE) |
| 76 | 77 | return -EIO; |
| @@ -79,7 +80,7 @@ static int ghash_update(struct shash_desc *desc, · 2 unmodified lines | ||
| 79 | 80 | |
| 80 | 81 | n = srclen & ~(GHASH_BLOCK_SIZE - 1); |
| 81 | 82 | if (n) { |
| 82 | − ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); | |
| 83 | + ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n); | |
| 83 | 84 | if (ret != n) |
| 84 | 85 | return -EIO; |
| 85 | 86 | src += n; |
| @@ -94,7 +95,7 @@ static int ghash_update(struct shash_desc *desc, · 8 unmodified lines | ||
| 94 | 95 | return 0; |
| 95 | 96 | } |
| 96 | 97 | |
| 97 | −static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) | |
| 98 | +static int ghash_flush(struct ghash_desc_ctx *dctx) | |
| 98 | 99 | { |
| 99 | 100 | u8 *buf = dctx->buffer; |
| 100 | 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 | 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 | 109 | if (ret != GHASH_BLOCK_SIZE) |
| 109 | 110 | return -EIO; |
| 111 | + | |
| 112 | + dctx->bytes = 0; | |
| 110 | 113 | } |
| 111 | 114 | |
| 112 | − dctx->bytes = 0; | |
| 113 | 115 | return 0; |
| 114 | 116 | } |
| 115 | 117 | |
| 116 | 118 | static int ghash_final(struct shash_desc *desc, u8 *dst) |
| 117 | 119 | { |
| 118 | 120 | struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); |
| 119 | − struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); | |
| 120 | 121 | int ret; |
| 121 | 122 | |
| 122 | − ret = ghash_flush(ctx, dctx); | |
| 123 | + ret = ghash_flush(dctx); | |
| 123 | 124 | if (!ret) |
| 124 | − memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); | |
| 125 | + memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE); | |
| 125 | 126 | return ret; |
| 126 | 127 | } |
| 127 | 128 | |