aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/authenc.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-11-22 10:11:53 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2008-01-10 16:16:30 -0500
commite236d4a89a2ffbc8aa18064161f4f159c4d89b4a (patch)
tree5688f2fd39c734c10b6d1fda791a87d7a19dee3b /crypto/authenc.c
parent7ba683a6deba70251756aa5a021cdaa5c875a7a2 (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>
Diffstat (limited to 'crypto/authenc.c')
-rw-r--r--crypto/authenc.c49
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 @@
23struct authenc_instance_ctx { 25struct 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
30struct crypto_authenc_ctx { 30struct crypto_authenc_ctx {
@@ -36,19 +36,31 @@ struct crypto_authenc_ctx {
36static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, 36static 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
71out: 83out:
72 return err; 84 return err;
85
86badkey:
87 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
88 goto out;
73} 89}
74 90
75static int crypto_authenc_hash(struct aead_request *req) 91static 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)