diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-11-22 10:11:53 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-01-10 16:16:30 -0500 |
commit | e236d4a89a2ffbc8aa18064161f4f159c4d89b4a (patch) | |
tree | 5688f2fd39c734c10b6d1fda791a87d7a19dee3b | |
parent | 7ba683a6deba70251756aa5a021cdaa5c875a7a2 (diff) |
[CRYPTO] authenc: Move enckeylen into key itself
Having enckeylen as a template parameter makes it a pain for hardware
devices that implement ciphers with many key sizes since each one would
have to be registered separately.
Since the authenc algorithm is mainly used for legacy purposes where its
key is going to be constructed out of two separate keys, we can in fact
embed this value into the key itself.
This patch does this by prepending an rtnetlink header to the key that
contains the encryption key length.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/authenc.c | 49 | ||||
-rw-r--r-- | include/crypto/authenc.h | 27 |
2 files changed, 56 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) |
diff --git a/include/crypto/authenc.h b/include/crypto/authenc.h new file mode 100644 index 000000000000..e47b044929a8 --- /dev/null +++ b/include/crypto/authenc.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * Authenc: Simple AEAD wrapper for IPsec | ||
3 | * | ||
4 | * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation; either version 2 of the License, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | */ | ||
12 | #ifndef _CRYPTO_AUTHENC_H | ||
13 | #define _CRYPTO_AUTHENC_H | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | enum { | ||
18 | CRYPTO_AUTHENC_KEYA_UNSPEC, | ||
19 | CRYPTO_AUTHENC_KEYA_PARAM, | ||
20 | }; | ||
21 | |||
22 | struct crypto_authenc_key_param { | ||
23 | __be32 enckeylen; | ||
24 | }; | ||
25 | |||
26 | #endif /* _CRYPTO_AUTHENC_H */ | ||
27 | |||