Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: chacha20poly1305 - use crypto_grab_ahash() and simplify error paths

Make the rfc7539 and rfc7539esp templates use the new function
crypto_grab_ahash() to initialize their ahash spawn.

This is needed to make all spawns be initialized in a consistent way.

Also simplify the error handling by taking advantage of crypto_drop_*()
now accepting (as a no-op) spawns that haven't been initialized yet, and
by taking advantage of crypto_grab_*() now handling ERR_PTR() names.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Eric Biggers and committed by
Herbert Xu
c282586f 05b3bbb5

+27 -57
+27 -57
crypto/chacha20poly1305.c
··· 16 16 #include <linux/kernel.h> 17 17 #include <linux/module.h> 18 18 19 - #include "internal.h" 20 - 21 19 struct chachapoly_instance_ctx { 22 20 struct crypto_skcipher_spawn chacha; 23 21 struct crypto_ahash_spawn poly; ··· 558 560 struct crypto_attr_type *algt; 559 561 u32 mask; 560 562 struct aead_instance *inst; 561 - struct skcipher_alg *chacha; 562 - struct crypto_alg *poly; 563 - struct hash_alg_common *poly_hash; 564 563 struct chachapoly_instance_ctx *ctx; 565 - const char *chacha_name, *poly_name; 564 + struct skcipher_alg *chacha; 565 + struct hash_alg_common *poly; 566 566 int err; 567 567 568 568 if (ivsize > CHACHAPOLY_IV_SIZE) ··· 575 579 576 580 mask = crypto_requires_sync(algt->type, algt->mask); 577 581 578 - chacha_name = crypto_attr_alg_name(tb[1]); 579 - if (IS_ERR(chacha_name)) 580 - return PTR_ERR(chacha_name); 581 - poly_name = crypto_attr_alg_name(tb[2]); 582 - if (IS_ERR(poly_name)) 583 - return PTR_ERR(poly_name); 584 - 585 - poly = crypto_find_alg(poly_name, &crypto_ahash_type, 586 - CRYPTO_ALG_TYPE_HASH, 587 - CRYPTO_ALG_TYPE_AHASH_MASK | mask); 588 - if (IS_ERR(poly)) 589 - return PTR_ERR(poly); 590 - poly_hash = __crypto_hash_alg_common(poly); 591 - 592 - err = -EINVAL; 593 - if (poly_hash->digestsize != POLY1305_DIGEST_SIZE) 594 - goto out_put_poly; 595 - 596 - err = -ENOMEM; 597 582 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); 598 583 if (!inst) 599 - goto out_put_poly; 600 - 584 + return -ENOMEM; 601 585 ctx = aead_instance_ctx(inst); 602 586 ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize; 603 - err = crypto_init_ahash_spawn(&ctx->poly, poly_hash, 604 - aead_crypto_instance(inst)); 605 - if (err) 606 - goto err_free_inst; 607 587 608 588 err = crypto_grab_skcipher(&ctx->chacha, aead_crypto_instance(inst), 609 - chacha_name, 0, mask); 589 + crypto_attr_alg_name(tb[1]), 0, mask); 610 590 if (err) 611 - goto err_drop_poly; 612 - 591 + goto err_free_inst; 613 592 chacha = crypto_spawn_skcipher_alg(&ctx->chacha); 614 593 594 + err = crypto_grab_ahash(&ctx->poly, aead_crypto_instance(inst), 595 + crypto_attr_alg_name(tb[2]), 0, mask); 596 + if (err) 597 + goto err_free_inst; 598 + poly = crypto_spawn_ahash_alg(&ctx->poly); 599 + 615 600 err = -EINVAL; 601 + if (poly->digestsize != POLY1305_DIGEST_SIZE) 602 + goto err_free_inst; 616 603 /* Need 16-byte IV size, including Initial Block Counter value */ 617 604 if (crypto_skcipher_alg_ivsize(chacha) != CHACHA_IV_SIZE) 618 - goto out_drop_chacha; 605 + goto err_free_inst; 619 606 /* Not a stream cipher? */ 620 607 if (chacha->base.cra_blocksize != 1) 621 - goto out_drop_chacha; 608 + goto err_free_inst; 622 609 623 610 err = -ENAMETOOLONG; 624 611 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, 625 612 "%s(%s,%s)", name, chacha->base.cra_name, 626 - poly->cra_name) >= CRYPTO_MAX_ALG_NAME) 627 - goto out_drop_chacha; 613 + poly->base.cra_name) >= CRYPTO_MAX_ALG_NAME) 614 + goto err_free_inst; 628 615 if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, 629 616 "%s(%s,%s)", name, chacha->base.cra_driver_name, 630 - poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 631 - goto out_drop_chacha; 617 + poly->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 618 + goto err_free_inst; 632 619 633 - inst->alg.base.cra_flags = (chacha->base.cra_flags | poly->cra_flags) & 634 - CRYPTO_ALG_ASYNC; 620 + inst->alg.base.cra_flags = (chacha->base.cra_flags | 621 + poly->base.cra_flags) & CRYPTO_ALG_ASYNC; 635 622 inst->alg.base.cra_priority = (chacha->base.cra_priority + 636 - poly->cra_priority) / 2; 623 + poly->base.cra_priority) / 2; 637 624 inst->alg.base.cra_blocksize = 1; 638 625 inst->alg.base.cra_alignmask = chacha->base.cra_alignmask | 639 - poly->cra_alignmask; 626 + poly->base.cra_alignmask; 640 627 inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) + 641 628 ctx->saltlen; 642 629 inst->alg.ivsize = ivsize; ··· 635 656 inst->free = chachapoly_free; 636 657 637 658 err = aead_register_instance(tmpl, inst); 638 - if (err) 639 - goto out_drop_chacha; 640 - 641 - out_put_poly: 642 - crypto_mod_put(poly); 643 - return err; 644 - 645 - out_drop_chacha: 646 - crypto_drop_skcipher(&ctx->chacha); 647 - err_drop_poly: 648 - crypto_drop_ahash(&ctx->poly); 659 + if (err) { 649 660 err_free_inst: 650 - kfree(inst); 651 - goto out_put_poly; 661 + chachapoly_free(inst); 662 + } 663 + return err; 652 664 } 653 665 654 666 static int rfc7539_create(struct crypto_template *tmpl, struct rtattr **tb)