Commit 7ba683a6deba70251756aa5a021cdaa5c875a7a2

Authored by Herbert Xu
1 parent e29bc6ad0e

[CRYPTO] aead: Make authsize a run-time parameter

As it is authsize is an algorithm paramter which cannot be changed at
run-time.  This is inconvenient because hardware that implements such
algorithms would have to register each authsize that they support
separately.

Since authsize is a property common to all AEAD algorithms, we can add
a function setauthsize that sets it at run-time, just like setkey.

This patch does exactly that and also changes authenc so that authsize
is no longer a parameter of its template.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Showing 4 changed files with 38 additions and 32 deletions Side-by-side Diff

... ... @@ -53,6 +53,24 @@
53 53 return aead->setkey(tfm, key, keylen);
54 54 }
55 55  
  56 +int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
  57 +{
  58 + int err;
  59 +
  60 + if (authsize > crypto_aead_alg(tfm)->maxauthsize)
  61 + return -EINVAL;
  62 +
  63 + if (crypto_aead_alg(tfm)->setauthsize) {
  64 + err = crypto_aead_alg(tfm)->setauthsize(tfm, authsize);
  65 + if (err)
  66 + return err;
  67 + }
  68 +
  69 + crypto_aead_crt(tfm)->authsize = authsize;
  70 + return 0;
  71 +}
  72 +EXPORT_SYMBOL_GPL(crypto_aead_setauthsize);
  73 +
56 74 static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type,
57 75 u32 mask)
58 76 {
59 77  
... ... @@ -64,14 +82,14 @@
64 82 struct aead_alg *alg = &tfm->__crt_alg->cra_aead;
65 83 struct aead_tfm *crt = &tfm->crt_aead;
66 84  
67   - if (max(alg->authsize, alg->ivsize) > PAGE_SIZE / 8)
  85 + if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
68 86 return -EINVAL;
69 87  
70 88 crt->setkey = setkey;
71 89 crt->encrypt = alg->encrypt;
72 90 crt->decrypt = alg->decrypt;
73 91 crt->ivsize = alg->ivsize;
74   - crt->authsize = alg->authsize;
  92 + crt->authsize = alg->maxauthsize;
75 93  
76 94 return 0;
77 95 }
... ... @@ -85,7 +103,7 @@
85 103 seq_printf(m, "type : aead\n");
86 104 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
87 105 seq_printf(m, "ivsize : %u\n", aead->ivsize);
88   - seq_printf(m, "authsize : %u\n", aead->authsize);
  106 + seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize);
89 107 }
90 108  
91 109 const struct crypto_type crypto_aead_type = {
... ... @@ -24,7 +24,6 @@
24 24 struct crypto_spawn auth;
25 25 struct crypto_spawn enc;
26 26  
27   - unsigned int authsize;
28 27 unsigned int enckeylen;
29 28 };
30 29  
... ... @@ -76,8 +75,6 @@
76 75 static int crypto_authenc_hash(struct aead_request *req)
77 76 {
78 77 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
79   - struct authenc_instance_ctx *ictx =
80   - crypto_instance_ctx(crypto_aead_alg_instance(authenc));
81 78 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
82 79 struct crypto_hash *auth = ctx->auth;
83 80 struct hash_desc desc = {
... ... @@ -111,7 +108,8 @@
111 108 if (err)
112 109 return err;
113 110  
114   - scatterwalk_map_and_copy(hash, dst, cryptlen, ictx->authsize, 1);
  111 + scatterwalk_map_and_copy(hash, dst, cryptlen,
  112 + crypto_aead_authsize(authenc), 1);
115 113 return 0;
116 114 }
117 115  
... ... @@ -147,8 +145,6 @@
147 145 static int crypto_authenc_verify(struct aead_request *req)
148 146 {
149 147 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
150   - struct authenc_instance_ctx *ictx =
151   - crypto_instance_ctx(crypto_aead_alg_instance(authenc));
152 148 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
153 149 struct crypto_hash *auth = ctx->auth;
154 150 struct hash_desc desc = {
... ... @@ -186,7 +182,7 @@
186 182 if (err)
187 183 return err;
188 184  
189   - authsize = ictx->authsize;
  185 + authsize = crypto_aead_authsize(authenc);
190 186 scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0);
191 187 return memcmp(ihash, ohash, authsize) ? -EINVAL : 0;
192 188 }
193 189  
... ... @@ -224,18 +220,12 @@
224 220 struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm);
225 221 struct crypto_hash *auth;
226 222 struct crypto_ablkcipher *enc;
227   - unsigned int digestsize;
228 223 int err;
229 224  
230 225 auth = crypto_spawn_hash(&ictx->auth);
231 226 if (IS_ERR(auth))
232 227 return PTR_ERR(auth);
233 228  
234   - err = -EINVAL;
235   - digestsize = crypto_hash_digestsize(auth);
236   - if (ictx->authsize > digestsize)
237   - goto err_free_hash;
238   -
239 229 enc = crypto_spawn_ablkcipher(&ictx->enc);
240 230 err = PTR_ERR(enc);
241 231 if (IS_ERR(enc))
... ... @@ -246,7 +236,7 @@
246 236 tfm->crt_aead.reqsize = max_t(unsigned int,
247 237 (crypto_hash_alignmask(auth) &
248 238 ~(crypto_tfm_ctx_alignment() - 1)) +
249   - digestsize * 2,
  239 + crypto_hash_digestsize(auth) * 2,
250 240 sizeof(struct ablkcipher_request) +
251 241 crypto_ablkcipher_reqsize(enc));
252 242  
... ... @@ -273,7 +263,6 @@
273 263 struct crypto_alg *auth;
274 264 struct crypto_alg *enc;
275 265 struct authenc_instance_ctx *ctx;
276   - unsigned int authsize;
277 266 unsigned int enckeylen;
278 267 int err;
279 268  
280 269  
... ... @@ -286,18 +275,13 @@
286 275 if (IS_ERR(auth))
287 276 return ERR_PTR(PTR_ERR(auth));
288 277  
289   - err = crypto_attr_u32(tb[2], &authsize);
290   - inst = ERR_PTR(err);
291   - if (err)
292   - goto out_put_auth;
293   -
294   - enc = crypto_attr_alg(tb[3], CRYPTO_ALG_TYPE_BLKCIPHER,
  278 + enc = crypto_attr_alg(tb[2], CRYPTO_ALG_TYPE_BLKCIPHER,
295 279 CRYPTO_ALG_TYPE_BLKCIPHER_MASK);
296 280 inst = ERR_PTR(PTR_ERR(enc));
297 281 if (IS_ERR(enc))
298 282 goto out_put_auth;
299 283  
300   - err = crypto_attr_u32(tb[4], &enckeylen);
  284 + err = crypto_attr_u32(tb[3], &enckeylen);
301 285 if (err)
302 286 goto out_put_enc;
303 287  
304 288  
305 289  
... ... @@ -308,18 +292,17 @@
308 292  
309 293 err = -ENAMETOOLONG;
310 294 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
311   - "authenc(%s,%u,%s,%u)", auth->cra_name, authsize,
  295 + "authenc(%s,%s,%u)", auth->cra_name,
312 296 enc->cra_name, enckeylen) >= CRYPTO_MAX_ALG_NAME)
313 297 goto err_free_inst;
314 298  
315 299 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
316   - "authenc(%s,%u,%s,%u)", auth->cra_driver_name,
317   - authsize, enc->cra_driver_name, enckeylen) >=
  300 + "authenc(%s,%s,%u)", auth->cra_driver_name,
  301 + enc->cra_driver_name, enckeylen) >=
318 302 CRYPTO_MAX_ALG_NAME)
319 303 goto err_free_inst;
320 304  
321 305 ctx = crypto_instance_ctx(inst);
322   - ctx->authsize = authsize;
323 306 ctx->enckeylen = enckeylen;
324 307  
325 308 err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK);
... ... @@ -337,7 +320,9 @@
337 320 inst->alg.cra_type = &crypto_aead_type;
338 321  
339 322 inst->alg.cra_aead.ivsize = enc->cra_blkcipher.ivsize;
340   - inst->alg.cra_aead.authsize = authsize;
  323 + inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ?
  324 + auth->cra_hash.digestsize :
  325 + auth->cra_digest.dia_digestsize;
341 326  
342 327 inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx);
343 328  
... ... @@ -414,7 +414,7 @@
414 414 inst->alg.cra_alignmask = __alignof__(u32) - 1;
415 415 inst->alg.cra_type = &crypto_aead_type;
416 416 inst->alg.cra_aead.ivsize = 12;
417   - inst->alg.cra_aead.authsize = 16;
  417 + inst->alg.cra_aead.maxauthsize = 16;
418 418 inst->alg.cra_ctxsize = sizeof(struct crypto_gcm_ctx);
419 419 inst->alg.cra_init = crypto_gcm_init_tfm;
420 420 inst->alg.cra_exit = crypto_gcm_exit_tfm;
include/linux/crypto.h
... ... @@ -187,11 +187,12 @@
187 187 struct aead_alg {
188 188 int (*setkey)(struct crypto_aead *tfm, const u8 *key,
189 189 unsigned int keylen);
  190 + int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize);
190 191 int (*encrypt)(struct aead_request *req);
191 192 int (*decrypt)(struct aead_request *req);
192 193  
193 194 unsigned int ivsize;
194   - unsigned int authsize;
  195 + unsigned int maxauthsize;
195 196 };
196 197  
197 198 struct blkcipher_alg {
... ... @@ -753,6 +754,8 @@
753 754 {
754 755 return crypto_aead_crt(tfm)->setkey(tfm, key, keylen);
755 756 }
  757 +
  758 +int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize);
756 759  
757 760 static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req)
758 761 {