Commit e236d4a89a2ffbc8aa18064161f4f159c4d89b4a

Authored by Herbert Xu
1 parent 7ba683a6de

[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>

Showing 2 changed files with 56 additions and 20 deletions Side-by-side Diff

... ... @@ -11,10 +11,12 @@
11 11 */
12 12  
13 13 #include <crypto/algapi.h>
  14 +#include <crypto/authenc.h>
14 15 #include <linux/err.h>
15 16 #include <linux/init.h>
16 17 #include <linux/kernel.h>
17 18 #include <linux/module.h>
  19 +#include <linux/rtnetlink.h>
18 20 #include <linux/slab.h>
19 21 #include <linux/spinlock.h>
20 22  
... ... @@ -23,8 +25,6 @@
23 25 struct authenc_instance_ctx {
24 26 struct crypto_spawn auth;
25 27 struct crypto_spawn enc;
26   -
27   - unsigned int enckeylen;
28 28 };
29 29  
30 30 struct crypto_authenc_ctx {
31 31  
32 32  
33 33  
... ... @@ -36,19 +36,31 @@
36 36 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
37 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 39 unsigned int authkeylen;
  40 + unsigned int enckeylen;
43 41 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
44 42 struct crypto_hash *auth = ctx->auth;
45 43 struct crypto_ablkcipher *enc = ctx->enc;
  44 + struct rtattr *rta = (void *)key;
  45 + struct crypto_authenc_key_param *param;
46 46 int err = -EINVAL;
47 47  
48   - if (keylen < enckeylen) {
49   - crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
50   - goto out;
51   - }
  48 + if (keylen < sizeof(*rta))
  49 + goto badkey;
  50 + if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
  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 64 authkeylen = keylen - enckeylen;
53 65  
54 66 crypto_hash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
... ... @@ -70,6 +82,10 @@
70 82  
71 83 out:
72 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 91 static int crypto_authenc_hash(struct aead_request *req)
... ... @@ -263,7 +279,6 @@
263 279 struct crypto_alg *auth;
264 280 struct crypto_alg *enc;
265 281 struct authenc_instance_ctx *ctx;
266   - unsigned int enckeylen;
267 282 int err;
268 283  
269 284 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD);
... ... @@ -281,10 +296,6 @@
281 296 if (IS_ERR(enc))
282 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 299 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
289 300 err = -ENOMEM;
290 301 if (!inst)
291 302  
292 303  
... ... @@ -292,18 +303,16 @@
292 303  
293 304 err = -ENAMETOOLONG;
294 305 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
295   - "authenc(%s,%s,%u)", auth->cra_name,
296   - enc->cra_name, enckeylen) >= CRYPTO_MAX_ALG_NAME)
  306 + "authenc(%s,%s)", auth->cra_name, enc->cra_name) >=
  307 + CRYPTO_MAX_ALG_NAME)
297 308 goto err_free_inst;
298 309  
299 310 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
300   - "authenc(%s,%s,%u)", auth->cra_driver_name,
301   - enc->cra_driver_name, enckeylen) >=
302   - CRYPTO_MAX_ALG_NAME)
  311 + "authenc(%s,%s)", auth->cra_driver_name,
  312 + enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
303 313 goto err_free_inst;
304 314  
305 315 ctx = crypto_instance_ctx(inst);
306   - ctx->enckeylen = enckeylen;
307 316  
308 317 err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK);
309 318 if (err)
include/crypto/authenc.h
  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 */