]>
Commit | Line | Data |
---|---|---|
580be4aa GKH |
1 | From f699594d436960160f6d5ba84ed4a222f20d11cd Mon Sep 17 00:00:00 2001 |
2 | From: Eric Biggers <ebiggers@google.com> | |
3 | Date: Thu, 18 Apr 2019 14:43:02 -0700 | |
4 | Subject: crypto: gcm - fix incompatibility between "gcm" and "gcm_base" | |
5 | ||
6 | From: Eric Biggers <ebiggers@google.com> | |
7 | ||
8 | commit f699594d436960160f6d5ba84ed4a222f20d11cd upstream. | |
9 | ||
10 | GCM instances can be created by either the "gcm" template, which only | |
11 | allows choosing the block cipher, e.g. "gcm(aes)"; or by "gcm_base", | |
12 | which allows choosing the ctr and ghash implementations, e.g. | |
13 | "gcm_base(ctr(aes-generic),ghash-generic)". | |
14 | ||
15 | However, a "gcm_base" instance prevents a "gcm" instance from being | |
16 | registered using the same implementations. Nor will the instance be | |
17 | found by lookups of "gcm". This can be used as a denial of service. | |
18 | Moreover, "gcm_base" instances are never tested by the crypto | |
19 | self-tests, even if there are compatible "gcm" tests. | |
20 | ||
21 | The root cause of these problems is that instances of the two templates | |
22 | use different cra_names. Therefore, fix these problems by making | |
23 | "gcm_base" instances set the same cra_name as "gcm" instances, e.g. | |
24 | "gcm(aes)" instead of "gcm_base(ctr(aes-generic),ghash-generic)". | |
25 | ||
26 | This requires extracting the block cipher name from the name of the ctr | |
27 | algorithm. It also requires starting to verify that the algorithms are | |
28 | really ctr and ghash, not something else entirely. But it would be | |
29 | bizarre if anyone were actually using non-gcm-compatible algorithms with | |
30 | gcm_base, so this shouldn't break anyone in practice. | |
31 | ||
32 | Fixes: d00aa19b507b ("[CRYPTO] gcm: Allow block cipher parameter") | |
33 | Cc: stable@vger.kernel.org | |
34 | Signed-off-by: Eric Biggers <ebiggers@google.com> | |
35 | Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> | |
36 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
37 | ||
38 | --- | |
39 | crypto/gcm.c | 34 +++++++++++----------------------- | |
40 | 1 file changed, 11 insertions(+), 23 deletions(-) | |
41 | ||
42 | --- a/crypto/gcm.c | |
43 | +++ b/crypto/gcm.c | |
44 | @@ -597,7 +597,6 @@ static void crypto_gcm_free(struct aead_ | |
45 | ||
46 | static int crypto_gcm_create_common(struct crypto_template *tmpl, | |
47 | struct rtattr **tb, | |
48 | - const char *full_name, | |
49 | const char *ctr_name, | |
50 | const char *ghash_name) | |
51 | { | |
52 | @@ -638,7 +637,8 @@ static int crypto_gcm_create_common(stru | |
53 | goto err_free_inst; | |
54 | ||
55 | err = -EINVAL; | |
56 | - if (ghash->digestsize != 16) | |
57 | + if (strcmp(ghash->base.cra_name, "ghash") != 0 || | |
58 | + ghash->digestsize != 16) | |
59 | goto err_drop_ghash; | |
60 | ||
61 | crypto_set_skcipher_spawn(&ctx->ctr, aead_crypto_instance(inst)); | |
62 | @@ -650,24 +650,24 @@ static int crypto_gcm_create_common(stru | |
63 | ||
64 | ctr = crypto_spawn_skcipher_alg(&ctx->ctr); | |
65 | ||
66 | - /* We only support 16-byte blocks. */ | |
67 | + /* The skcipher algorithm must be CTR mode, using 16-byte blocks. */ | |
68 | err = -EINVAL; | |
69 | - if (crypto_skcipher_alg_ivsize(ctr) != 16) | |
70 | + if (strncmp(ctr->base.cra_name, "ctr(", 4) != 0 || | |
71 | + crypto_skcipher_alg_ivsize(ctr) != 16 || | |
72 | + ctr->base.cra_blocksize != 1) | |
73 | goto out_put_ctr; | |
74 | ||
75 | - /* Not a stream cipher? */ | |
76 | - if (ctr->base.cra_blocksize != 1) | |
77 | + err = -ENAMETOOLONG; | |
78 | + if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, | |
79 | + "gcm(%s", ctr->base.cra_name + 4) >= CRYPTO_MAX_ALG_NAME) | |
80 | goto out_put_ctr; | |
81 | ||
82 | - err = -ENAMETOOLONG; | |
83 | if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, | |
84 | "gcm_base(%s,%s)", ctr->base.cra_driver_name, | |
85 | ghash_alg->cra_driver_name) >= | |
86 | CRYPTO_MAX_ALG_NAME) | |
87 | goto out_put_ctr; | |
88 | ||
89 | - memcpy(inst->alg.base.cra_name, full_name, CRYPTO_MAX_ALG_NAME); | |
90 | - | |
91 | inst->alg.base.cra_flags = (ghash->base.cra_flags | | |
92 | ctr->base.cra_flags) & CRYPTO_ALG_ASYNC; | |
93 | inst->alg.base.cra_priority = (ghash->base.cra_priority + | |
94 | @@ -709,7 +709,6 @@ static int crypto_gcm_create(struct cryp | |
95 | { | |
96 | const char *cipher_name; | |
97 | char ctr_name[CRYPTO_MAX_ALG_NAME]; | |
98 | - char full_name[CRYPTO_MAX_ALG_NAME]; | |
99 | ||
100 | cipher_name = crypto_attr_alg_name(tb[1]); | |
101 | if (IS_ERR(cipher_name)) | |
102 | @@ -719,12 +718,7 @@ static int crypto_gcm_create(struct cryp | |
103 | CRYPTO_MAX_ALG_NAME) | |
104 | return -ENAMETOOLONG; | |
105 | ||
106 | - if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm(%s)", cipher_name) >= | |
107 | - CRYPTO_MAX_ALG_NAME) | |
108 | - return -ENAMETOOLONG; | |
109 | - | |
110 | - return crypto_gcm_create_common(tmpl, tb, full_name, | |
111 | - ctr_name, "ghash"); | |
112 | + return crypto_gcm_create_common(tmpl, tb, ctr_name, "ghash"); | |
113 | } | |
114 | ||
115 | static struct crypto_template crypto_gcm_tmpl = { | |
116 | @@ -738,7 +732,6 @@ static int crypto_gcm_base_create(struct | |
117 | { | |
118 | const char *ctr_name; | |
119 | const char *ghash_name; | |
120 | - char full_name[CRYPTO_MAX_ALG_NAME]; | |
121 | ||
122 | ctr_name = crypto_attr_alg_name(tb[1]); | |
123 | if (IS_ERR(ctr_name)) | |
124 | @@ -748,12 +741,7 @@ static int crypto_gcm_base_create(struct | |
125 | if (IS_ERR(ghash_name)) | |
126 | return PTR_ERR(ghash_name); | |
127 | ||
128 | - if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm_base(%s,%s)", | |
129 | - ctr_name, ghash_name) >= CRYPTO_MAX_ALG_NAME) | |
130 | - return -ENAMETOOLONG; | |
131 | - | |
132 | - return crypto_gcm_create_common(tmpl, tb, full_name, | |
133 | - ctr_name, ghash_name); | |
134 | + return crypto_gcm_create_common(tmpl, tb, ctr_name, ghash_name); | |
135 | } | |
136 | ||
137 | static struct crypto_template crypto_gcm_base_tmpl = { |