summaryrefslogtreecommitdiffstats
path: root/crypto/aead.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-05-21 03:11:13 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-05-21 23:25:56 -0400
commit856e3f4092cfd9ea6d6564e73f5bce5a0ac3cae3 (patch)
tree8e8c87713974a5332957d16758413a7fa5258d4c /crypto/aead.c
parent74412fd5d71b6eda0beb302aa467da000f0d530c (diff)
crypto: seqiv - Add support for new AEAD interface
This patch converts the seqiv IV generator to work with the new AEAD interface where IV generators are just normal AEAD algorithms. Full backwards compatibility is paramount at this point since no users have yet switched over to the new interface. Nor can they switch to the new interface until IV generation is fully supported by it. So this means we are adding two versions of seqiv alongside the existing one. The first one is the one that will be used when the underlying AEAD algorithm has switched over to the new AEAD interface. The second one handles the current case where the underlying AEAD algorithm still uses the old interface. Both versions export themselves through the new AEAD interface. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/aead.c')
-rw-r--r--crypto/aead.c100
1 files changed, 63 insertions, 37 deletions
diff --git a/crypto/aead.c b/crypto/aead.c
index d231e2837bfd..5fa992ac219c 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -378,15 +378,16 @@ static int crypto_grab_nivaead(struct crypto_aead_spawn *spawn,
378 return crypto_grab_spawn(&spawn->base, name, type, mask); 378 return crypto_grab_spawn(&spawn->base, name, type, mask);
379} 379}
380 380
381struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl, 381struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
382 struct rtattr **tb, u32 type, 382 struct rtattr **tb, u32 type, u32 mask)
383 u32 mask)
384{ 383{
385 const char *name; 384 const char *name;
386 struct crypto_aead_spawn *spawn; 385 struct crypto_aead_spawn *spawn;
387 struct crypto_attr_type *algt; 386 struct crypto_attr_type *algt;
388 struct crypto_instance *inst; 387 struct aead_instance *inst;
389 struct crypto_alg *alg; 388 struct aead_alg *alg;
389 unsigned int ivsize;
390 unsigned int maxauthsize;
390 int err; 391 int err;
391 392
392 algt = crypto_get_attr_type(tb); 393 algt = crypto_get_attr_type(tb);
@@ -405,20 +406,28 @@ struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl,
405 if (!inst) 406 if (!inst)
406 return ERR_PTR(-ENOMEM); 407 return ERR_PTR(-ENOMEM);
407 408
408 spawn = crypto_instance_ctx(inst); 409 spawn = aead_instance_ctx(inst);
409 410
410 /* Ignore async algorithms if necessary. */ 411 /* Ignore async algorithms if necessary. */
411 mask |= crypto_requires_sync(algt->type, algt->mask); 412 mask |= crypto_requires_sync(algt->type, algt->mask);
412 413
413 crypto_set_aead_spawn(spawn, inst); 414 crypto_set_aead_spawn(spawn, aead_crypto_instance(inst));
414 err = crypto_grab_nivaead(spawn, name, type, mask); 415 err = crypto_grab_nivaead(spawn, name, type, mask);
415 if (err) 416 if (err)
416 goto err_free_inst; 417 goto err_free_inst;
417 418
418 alg = crypto_aead_spawn_alg(spawn); 419 alg = crypto_spawn_aead_alg(spawn);
420
421 if (alg->base.cra_aead.encrypt) {
422 ivsize = alg->base.cra_aead.ivsize;
423 maxauthsize = alg->base.cra_aead.maxauthsize;
424 } else {
425 ivsize = alg->ivsize;
426 maxauthsize = alg->maxauthsize;
427 }
419 428
420 err = -EINVAL; 429 err = -EINVAL;
421 if (!alg->cra_aead.ivsize) 430 if (!ivsize)
422 goto err_drop_alg; 431 goto err_drop_alg;
423 432
424 /* 433 /*
@@ -427,39 +436,56 @@ struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl,
427 * template name and double-check the IV generator. 436 * template name and double-check the IV generator.
428 */ 437 */
429 if (algt->mask & CRYPTO_ALG_GENIV) { 438 if (algt->mask & CRYPTO_ALG_GENIV) {
430 if (strcmp(tmpl->name, alg->cra_aead.geniv)) 439 if (!alg->base.cra_aead.encrypt)
440 goto err_drop_alg;
441 if (strcmp(tmpl->name, alg->base.cra_aead.geniv))
431 goto err_drop_alg; 442 goto err_drop_alg;
432 443
433 memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); 444 memcpy(inst->alg.base.cra_name, alg->base.cra_name,
434 memcpy(inst->alg.cra_driver_name, alg->cra_driver_name,
435 CRYPTO_MAX_ALG_NAME); 445 CRYPTO_MAX_ALG_NAME);
436 } else { 446 memcpy(inst->alg.base.cra_driver_name,
437 err = -ENAMETOOLONG; 447 alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME);
438 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, 448
439 "%s(%s)", tmpl->name, alg->cra_name) >= 449 inst->alg.base.cra_flags = CRYPTO_ALG_TYPE_AEAD |
440 CRYPTO_MAX_ALG_NAME) 450 CRYPTO_ALG_GENIV;
441 goto err_drop_alg; 451 inst->alg.base.cra_flags |= alg->base.cra_flags &
442 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, 452 CRYPTO_ALG_ASYNC;
443 "%s(%s)", tmpl->name, alg->cra_driver_name) >= 453 inst->alg.base.cra_priority = alg->base.cra_priority;
444 CRYPTO_MAX_ALG_NAME) 454 inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
445 goto err_drop_alg; 455 inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
456 inst->alg.base.cra_type = &crypto_aead_type;
457
458 inst->alg.base.cra_aead.ivsize = ivsize;
459 inst->alg.base.cra_aead.maxauthsize = maxauthsize;
460
461 inst->alg.base.cra_aead.setkey = alg->base.cra_aead.setkey;
462 inst->alg.base.cra_aead.setauthsize =
463 alg->base.cra_aead.setauthsize;
464 inst->alg.base.cra_aead.encrypt = alg->base.cra_aead.encrypt;
465 inst->alg.base.cra_aead.decrypt = alg->base.cra_aead.decrypt;
466
467 goto out;
446 } 468 }
447 469
448 inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_GENIV; 470 err = -ENAMETOOLONG;
449 inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC; 471 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
450 inst->alg.cra_priority = alg->cra_priority; 472 "%s(%s)", tmpl->name, alg->base.cra_name) >=
451 inst->alg.cra_blocksize = alg->cra_blocksize; 473 CRYPTO_MAX_ALG_NAME)
452 inst->alg.cra_alignmask = alg->cra_alignmask; 474 goto err_drop_alg;
453 inst->alg.cra_type = &crypto_aead_type; 475 if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
476 "%s(%s)", tmpl->name, alg->base.cra_driver_name) >=
477 CRYPTO_MAX_ALG_NAME)
478 goto err_drop_alg;
454 479
455 inst->alg.cra_aead.ivsize = alg->cra_aead.ivsize; 480 inst->alg.base.cra_flags = CRYPTO_ALG_TYPE_AEAD;
456 inst->alg.cra_aead.maxauthsize = alg->cra_aead.maxauthsize; 481 inst->alg.base.cra_flags |= alg->base.cra_flags & CRYPTO_ALG_ASYNC;
457 inst->alg.cra_aead.geniv = alg->cra_aead.geniv; 482 inst->alg.base.cra_priority = alg->base.cra_priority;
483 inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
484 inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
485 inst->alg.base.cra_type = &crypto_new_aead_type;
458 486
459 inst->alg.cra_aead.setkey = alg->cra_aead.setkey; 487 inst->alg.ivsize = ivsize;
460 inst->alg.cra_aead.setauthsize = alg->cra_aead.setauthsize; 488 inst->alg.maxauthsize = maxauthsize;
461 inst->alg.cra_aead.encrypt = alg->cra_aead.encrypt;
462 inst->alg.cra_aead.decrypt = alg->cra_aead.decrypt;
463 489
464out: 490out:
465 return inst; 491 return inst;
@@ -473,9 +499,9 @@ err_free_inst:
473} 499}
474EXPORT_SYMBOL_GPL(aead_geniv_alloc); 500EXPORT_SYMBOL_GPL(aead_geniv_alloc);
475 501
476void aead_geniv_free(struct crypto_instance *inst) 502void aead_geniv_free(struct aead_instance *inst)
477{ 503{
478 crypto_drop_aead(crypto_instance_ctx(inst)); 504 crypto_drop_aead(aead_instance_ctx(inst));
479 kfree(inst); 505 kfree(inst);
480} 506}
481EXPORT_SYMBOL_GPL(aead_geniv_free); 507EXPORT_SYMBOL_GPL(aead_geniv_free);