diff options
Diffstat (limited to 'crypto/authenc.c')
-rw-r--r-- | crypto/authenc.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/crypto/authenc.c b/crypto/authenc.c index 5df5fb169cbe..a61dea1c2fe6 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c | |||
@@ -11,10 +11,12 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <crypto/algapi.h> | 13 | #include <crypto/algapi.h> |
14 | #include <crypto/authenc.h> | ||
14 | #include <linux/err.h> | 15 | #include <linux/err.h> |
15 | #include <linux/init.h> | 16 | #include <linux/init.h> |
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/rtnetlink.h> | ||
18 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
19 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
20 | 22 | ||
@@ -23,8 +25,6 @@ | |||
23 | struct authenc_instance_ctx { | 25 | struct authenc_instance_ctx { |
24 | struct crypto_spawn auth; | 26 | struct crypto_spawn auth; |
25 | struct crypto_spawn enc; | 27 | struct crypto_spawn enc; |
26 | |||
27 | unsigned int enckeylen; | ||
28 | }; | 28 | }; |
29 | 29 | ||
30 | struct crypto_authenc_ctx { | 30 | struct crypto_authenc_ctx { |
@@ -36,19 +36,31 @@ struct crypto_authenc_ctx { | |||
36 | static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, | 36 | static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, |
37 | unsigned int keylen) | 37 | unsigned int keylen) |
38 | { | 38 | { |
39 | struct authenc_instance_ctx *ictx = | ||
40 | crypto_instance_ctx(crypto_aead_alg_instance(authenc)); | ||
41 | unsigned int enckeylen = ictx->enckeylen; | ||
42 | unsigned int authkeylen; | 39 | unsigned int authkeylen; |
40 | unsigned int enckeylen; | ||
43 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); | 41 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); |
44 | struct crypto_hash *auth = ctx->auth; | 42 | struct crypto_hash *auth = ctx->auth; |
45 | struct crypto_ablkcipher *enc = ctx->enc; | 43 | struct crypto_ablkcipher *enc = ctx->enc; |
44 | struct rtattr *rta = (void *)key; | ||
45 | struct crypto_authenc_key_param *param; | ||
46 | int err = -EINVAL; | 46 | int err = -EINVAL; |
47 | 47 | ||
48 | if (keylen < enckeylen) { | 48 | if (keylen < sizeof(*rta)) |
49 | crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); | 49 | goto badkey; |
50 | goto out; | 50 | if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) |
51 | } | 51 | goto badkey; |
52 | if (RTA_PAYLOAD(rta) < sizeof(*param)) | ||
53 | goto badkey; | ||
54 | |||
55 | param = RTA_DATA(rta); | ||
56 | enckeylen = be32_to_cpu(param->enckeylen); | ||
57 | |||
58 | key += RTA_ALIGN(rta->rta_len); | ||
59 | keylen -= RTA_ALIGN(rta->rta_len); | ||
60 | |||
61 | if (keylen < enckeylen) | ||
62 | goto badkey; | ||
63 | |||
52 | authkeylen = keylen - enckeylen; | 64 | authkeylen = keylen - enckeylen; |
53 | 65 | ||
54 | crypto_hash_clear_flags(auth, CRYPTO_TFM_REQ_MASK); | 66 | crypto_hash_clear_flags(auth, CRYPTO_TFM_REQ_MASK); |
@@ -70,6 +82,10 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, | |||
70 | 82 | ||
71 | out: | 83 | out: |
72 | return err; | 84 | return err; |
85 | |||
86 | badkey: | ||
87 | crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
88 | goto out; | ||
73 | } | 89 | } |
74 | 90 | ||
75 | static int crypto_authenc_hash(struct aead_request *req) | 91 | static int crypto_authenc_hash(struct aead_request *req) |
@@ -263,7 +279,6 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) | |||
263 | struct crypto_alg *auth; | 279 | struct crypto_alg *auth; |
264 | struct crypto_alg *enc; | 280 | struct crypto_alg *enc; |
265 | struct authenc_instance_ctx *ctx; | 281 | struct authenc_instance_ctx *ctx; |
266 | unsigned int enckeylen; | ||
267 | int err; | 282 | int err; |
268 | 283 | ||
269 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD); | 284 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD); |
@@ -281,10 +296,6 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) | |||
281 | if (IS_ERR(enc)) | 296 | if (IS_ERR(enc)) |
282 | goto out_put_auth; | 297 | goto out_put_auth; |
283 | 298 | ||
284 | err = crypto_attr_u32(tb[3], &enckeylen); | ||
285 | if (err) | ||
286 | goto out_put_enc; | ||
287 | |||
288 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); | 299 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); |
289 | err = -ENOMEM; | 300 | err = -ENOMEM; |
290 | if (!inst) | 301 | if (!inst) |
@@ -292,18 +303,16 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) | |||
292 | 303 | ||
293 | err = -ENAMETOOLONG; | 304 | err = -ENAMETOOLONG; |
294 | if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, | 305 | if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, |
295 | "authenc(%s,%s,%u)", auth->cra_name, | 306 | "authenc(%s,%s)", auth->cra_name, enc->cra_name) >= |
296 | enc->cra_name, enckeylen) >= CRYPTO_MAX_ALG_NAME) | 307 | CRYPTO_MAX_ALG_NAME) |
297 | goto err_free_inst; | 308 | goto err_free_inst; |
298 | 309 | ||
299 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, | 310 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
300 | "authenc(%s,%s,%u)", auth->cra_driver_name, | 311 | "authenc(%s,%s)", auth->cra_driver_name, |
301 | enc->cra_driver_name, enckeylen) >= | 312 | enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) |
302 | CRYPTO_MAX_ALG_NAME) | ||
303 | goto err_free_inst; | 313 | goto err_free_inst; |
304 | 314 | ||
305 | ctx = crypto_instance_ctx(inst); | 315 | ctx = crypto_instance_ctx(inst); |
306 | ctx->enckeylen = enckeylen; | ||
307 | 316 | ||
308 | err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK); | 317 | err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK); |
309 | if (err) | 318 | if (err) |