aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Cerri <marcelo.cerri@canonical.com>2016-09-28 12:42:10 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2016-10-02 10:26:42 -0400
commit80da44c29d997e28c4442825f35f4ac339813877 (patch)
tree07d05485c86275960e270a968ded8baded310d2a
parenta397ba829d7f8aff4c90af3704573a28ccd61a59 (diff)
crypto: vmx - Fix memory corruption caused by p8_ghash
This patch changes the p8_ghash driver to use ghash-generic as a fixed fallback implementation. This allows the correct value of descsize to be defined directly in its shash_alg structure and avoids problems with incorrect buffer sizes when its state is exported or imported. Reported-by: Jan Stancek <jstancek@redhat.com> Fixes: cc333cd68dfa ("crypto: vmx - Adding GHASH routines for VMX module") Cc: stable@vger.kernel.org Signed-off-by: Marcelo Cerri <marcelo.cerri@canonical.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/vmx/ghash.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c
index 6c999cb01b80..27a94a119009 100644
--- a/drivers/crypto/vmx/ghash.c
+++ b/drivers/crypto/vmx/ghash.c
@@ -26,16 +26,13 @@
26#include <linux/hardirq.h> 26#include <linux/hardirq.h>
27#include <asm/switch_to.h> 27#include <asm/switch_to.h>
28#include <crypto/aes.h> 28#include <crypto/aes.h>
29#include <crypto/ghash.h>
29#include <crypto/scatterwalk.h> 30#include <crypto/scatterwalk.h>
30#include <crypto/internal/hash.h> 31#include <crypto/internal/hash.h>
31#include <crypto/b128ops.h> 32#include <crypto/b128ops.h>
32 33
33#define IN_INTERRUPT in_interrupt() 34#define IN_INTERRUPT in_interrupt()
34 35
35#define GHASH_BLOCK_SIZE (16)
36#define GHASH_DIGEST_SIZE (16)
37#define GHASH_KEY_LEN (16)
38
39void gcm_init_p8(u128 htable[16], const u64 Xi[2]); 36void gcm_init_p8(u128 htable[16], const u64 Xi[2]);
40void gcm_gmult_p8(u64 Xi[2], const u128 htable[16]); 37void gcm_gmult_p8(u64 Xi[2], const u128 htable[16]);
41void gcm_ghash_p8(u64 Xi[2], const u128 htable[16], 38void gcm_ghash_p8(u64 Xi[2], const u128 htable[16],
@@ -55,16 +52,11 @@ struct p8_ghash_desc_ctx {
55 52
56static int p8_ghash_init_tfm(struct crypto_tfm *tfm) 53static int p8_ghash_init_tfm(struct crypto_tfm *tfm)
57{ 54{
58 const char *alg; 55 const char *alg = "ghash-generic";
59 struct crypto_shash *fallback; 56 struct crypto_shash *fallback;
60 struct crypto_shash *shash_tfm = __crypto_shash_cast(tfm); 57 struct crypto_shash *shash_tfm = __crypto_shash_cast(tfm);
61 struct p8_ghash_ctx *ctx = crypto_tfm_ctx(tfm); 58 struct p8_ghash_ctx *ctx = crypto_tfm_ctx(tfm);
62 59
63 if (!(alg = crypto_tfm_alg_name(tfm))) {
64 printk(KERN_ERR "Failed to get algorithm name.\n");
65 return -ENOENT;
66 }
67
68 fallback = crypto_alloc_shash(alg, 0, CRYPTO_ALG_NEED_FALLBACK); 60 fallback = crypto_alloc_shash(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
69 if (IS_ERR(fallback)) { 61 if (IS_ERR(fallback)) {
70 printk(KERN_ERR 62 printk(KERN_ERR
@@ -78,10 +70,18 @@ static int p8_ghash_init_tfm(struct crypto_tfm *tfm)
78 crypto_shash_set_flags(fallback, 70 crypto_shash_set_flags(fallback,
79 crypto_shash_get_flags((struct crypto_shash 71 crypto_shash_get_flags((struct crypto_shash
80 *) tfm)); 72 *) tfm));
81 ctx->fallback = fallback;
82 73
83 shash_tfm->descsize = sizeof(struct p8_ghash_desc_ctx) 74 /* Check if the descsize defined in the algorithm is still enough. */
84 + crypto_shash_descsize(fallback); 75 if (shash_tfm->descsize < sizeof(struct p8_ghash_desc_ctx)
76 + crypto_shash_descsize(fallback)) {
77 printk(KERN_ERR
78 "Desc size of the fallback implementation (%s) does not match the expected value: %lu vs %u\n",
79 alg,
80 shash_tfm->descsize - sizeof(struct p8_ghash_desc_ctx),
81 crypto_shash_descsize(fallback));
82 return -EINVAL;
83 }
84 ctx->fallback = fallback;
85 85
86 return 0; 86 return 0;
87} 87}
@@ -113,7 +113,7 @@ static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key,
113{ 113{
114 struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(tfm)); 114 struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(tfm));
115 115
116 if (keylen != GHASH_KEY_LEN) 116 if (keylen != GHASH_BLOCK_SIZE)
117 return -EINVAL; 117 return -EINVAL;
118 118
119 preempt_disable(); 119 preempt_disable();
@@ -211,7 +211,8 @@ struct shash_alg p8_ghash_alg = {
211 .update = p8_ghash_update, 211 .update = p8_ghash_update,
212 .final = p8_ghash_final, 212 .final = p8_ghash_final,
213 .setkey = p8_ghash_setkey, 213 .setkey = p8_ghash_setkey,
214 .descsize = sizeof(struct p8_ghash_desc_ctx), 214 .descsize = sizeof(struct p8_ghash_desc_ctx)
215 + sizeof(struct ghash_desc_ctx),
215 .base = { 216 .base = {
216 .cra_name = "ghash", 217 .cra_name = "ghash",
217 .cra_driver_name = "p8_ghash", 218 .cra_driver_name = "p8_ghash",