diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2016-07-12 01:17:40 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-07-18 05:35:41 -0400 |
commit | 1e1f006112b50640d7fc11851346f906d223df09 (patch) | |
tree | b2bfcc3cc716d88628b8b7561e98791162aa27b1 /crypto | |
parent | 16f37ecdd068884fc4f4177f83ac77910f4fc113 (diff) |
crypto: chacha20poly1305 - Use skcipher
This patch converts chacha20poly1305 to use the new skcipher
interface as opposed to ablkcipher.
It also fixes a buglet where we may end up with an async poly1305
when the user asks for a async algorithm. This shouldn't be a
problem yet as there aren't any async implementations of poly1305
out there.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/chacha20poly1305.c | 89 |
1 files changed, 46 insertions, 43 deletions
diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c index 7b6b935cef23..e899ef51dc8e 100644 --- a/crypto/chacha20poly1305.c +++ b/crypto/chacha20poly1305.c | |||
@@ -31,7 +31,7 @@ struct chachapoly_instance_ctx { | |||
31 | }; | 31 | }; |
32 | 32 | ||
33 | struct chachapoly_ctx { | 33 | struct chachapoly_ctx { |
34 | struct crypto_ablkcipher *chacha; | 34 | struct crypto_skcipher *chacha; |
35 | struct crypto_ahash *poly; | 35 | struct crypto_ahash *poly; |
36 | /* key bytes we use for the ChaCha20 IV */ | 36 | /* key bytes we use for the ChaCha20 IV */ |
37 | unsigned int saltlen; | 37 | unsigned int saltlen; |
@@ -53,7 +53,7 @@ struct poly_req { | |||
53 | struct chacha_req { | 53 | struct chacha_req { |
54 | u8 iv[CHACHA20_IV_SIZE]; | 54 | u8 iv[CHACHA20_IV_SIZE]; |
55 | struct scatterlist src[1]; | 55 | struct scatterlist src[1]; |
56 | struct ablkcipher_request req; /* must be last member */ | 56 | struct skcipher_request req; /* must be last member */ |
57 | }; | 57 | }; |
58 | 58 | ||
59 | struct chachapoly_req_ctx { | 59 | struct chachapoly_req_ctx { |
@@ -144,12 +144,12 @@ static int chacha_decrypt(struct aead_request *req) | |||
144 | dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen); | 144 | dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen); |
145 | } | 145 | } |
146 | 146 | ||
147 | ablkcipher_request_set_callback(&creq->req, aead_request_flags(req), | 147 | skcipher_request_set_callback(&creq->req, aead_request_flags(req), |
148 | chacha_decrypt_done, req); | 148 | chacha_decrypt_done, req); |
149 | ablkcipher_request_set_tfm(&creq->req, ctx->chacha); | 149 | skcipher_request_set_tfm(&creq->req, ctx->chacha); |
150 | ablkcipher_request_set_crypt(&creq->req, src, dst, | 150 | skcipher_request_set_crypt(&creq->req, src, dst, |
151 | rctx->cryptlen, creq->iv); | 151 | rctx->cryptlen, creq->iv); |
152 | err = crypto_ablkcipher_decrypt(&creq->req); | 152 | err = crypto_skcipher_decrypt(&creq->req); |
153 | if (err) | 153 | if (err) |
154 | return err; | 154 | return err; |
155 | 155 | ||
@@ -393,13 +393,13 @@ static int poly_genkey(struct aead_request *req) | |||
393 | 393 | ||
394 | chacha_iv(creq->iv, req, 0); | 394 | chacha_iv(creq->iv, req, 0); |
395 | 395 | ||
396 | ablkcipher_request_set_callback(&creq->req, aead_request_flags(req), | 396 | skcipher_request_set_callback(&creq->req, aead_request_flags(req), |
397 | poly_genkey_done, req); | 397 | poly_genkey_done, req); |
398 | ablkcipher_request_set_tfm(&creq->req, ctx->chacha); | 398 | skcipher_request_set_tfm(&creq->req, ctx->chacha); |
399 | ablkcipher_request_set_crypt(&creq->req, creq->src, creq->src, | 399 | skcipher_request_set_crypt(&creq->req, creq->src, creq->src, |
400 | POLY1305_KEY_SIZE, creq->iv); | 400 | POLY1305_KEY_SIZE, creq->iv); |
401 | 401 | ||
402 | err = crypto_ablkcipher_decrypt(&creq->req); | 402 | err = crypto_skcipher_decrypt(&creq->req); |
403 | if (err) | 403 | if (err) |
404 | return err; | 404 | return err; |
405 | 405 | ||
@@ -433,12 +433,12 @@ static int chacha_encrypt(struct aead_request *req) | |||
433 | dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen); | 433 | dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen); |
434 | } | 434 | } |
435 | 435 | ||
436 | ablkcipher_request_set_callback(&creq->req, aead_request_flags(req), | 436 | skcipher_request_set_callback(&creq->req, aead_request_flags(req), |
437 | chacha_encrypt_done, req); | 437 | chacha_encrypt_done, req); |
438 | ablkcipher_request_set_tfm(&creq->req, ctx->chacha); | 438 | skcipher_request_set_tfm(&creq->req, ctx->chacha); |
439 | ablkcipher_request_set_crypt(&creq->req, src, dst, | 439 | skcipher_request_set_crypt(&creq->req, src, dst, |
440 | req->cryptlen, creq->iv); | 440 | req->cryptlen, creq->iv); |
441 | err = crypto_ablkcipher_encrypt(&creq->req); | 441 | err = crypto_skcipher_encrypt(&creq->req); |
442 | if (err) | 442 | if (err) |
443 | return err; | 443 | return err; |
444 | 444 | ||
@@ -500,13 +500,13 @@ static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, | |||
500 | keylen -= ctx->saltlen; | 500 | keylen -= ctx->saltlen; |
501 | memcpy(ctx->salt, key + keylen, ctx->saltlen); | 501 | memcpy(ctx->salt, key + keylen, ctx->saltlen); |
502 | 502 | ||
503 | crypto_ablkcipher_clear_flags(ctx->chacha, CRYPTO_TFM_REQ_MASK); | 503 | crypto_skcipher_clear_flags(ctx->chacha, CRYPTO_TFM_REQ_MASK); |
504 | crypto_ablkcipher_set_flags(ctx->chacha, crypto_aead_get_flags(aead) & | 504 | crypto_skcipher_set_flags(ctx->chacha, crypto_aead_get_flags(aead) & |
505 | CRYPTO_TFM_REQ_MASK); | 505 | CRYPTO_TFM_REQ_MASK); |
506 | 506 | ||
507 | err = crypto_ablkcipher_setkey(ctx->chacha, key, keylen); | 507 | err = crypto_skcipher_setkey(ctx->chacha, key, keylen); |
508 | crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctx->chacha) & | 508 | crypto_aead_set_flags(aead, crypto_skcipher_get_flags(ctx->chacha) & |
509 | CRYPTO_TFM_RES_MASK); | 509 | CRYPTO_TFM_RES_MASK); |
510 | return err; | 510 | return err; |
511 | } | 511 | } |
512 | 512 | ||
@@ -524,7 +524,7 @@ static int chachapoly_init(struct crypto_aead *tfm) | |||
524 | struct aead_instance *inst = aead_alg_instance(tfm); | 524 | struct aead_instance *inst = aead_alg_instance(tfm); |
525 | struct chachapoly_instance_ctx *ictx = aead_instance_ctx(inst); | 525 | struct chachapoly_instance_ctx *ictx = aead_instance_ctx(inst); |
526 | struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); | 526 | struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); |
527 | struct crypto_ablkcipher *chacha; | 527 | struct crypto_skcipher *chacha; |
528 | struct crypto_ahash *poly; | 528 | struct crypto_ahash *poly; |
529 | unsigned long align; | 529 | unsigned long align; |
530 | 530 | ||
@@ -532,7 +532,7 @@ static int chachapoly_init(struct crypto_aead *tfm) | |||
532 | if (IS_ERR(poly)) | 532 | if (IS_ERR(poly)) |
533 | return PTR_ERR(poly); | 533 | return PTR_ERR(poly); |
534 | 534 | ||
535 | chacha = crypto_spawn_skcipher(&ictx->chacha); | 535 | chacha = crypto_spawn_skcipher2(&ictx->chacha); |
536 | if (IS_ERR(chacha)) { | 536 | if (IS_ERR(chacha)) { |
537 | crypto_free_ahash(poly); | 537 | crypto_free_ahash(poly); |
538 | return PTR_ERR(chacha); | 538 | return PTR_ERR(chacha); |
@@ -548,8 +548,8 @@ static int chachapoly_init(struct crypto_aead *tfm) | |||
548 | tfm, | 548 | tfm, |
549 | align + offsetof(struct chachapoly_req_ctx, u) + | 549 | align + offsetof(struct chachapoly_req_ctx, u) + |
550 | max(offsetof(struct chacha_req, req) + | 550 | max(offsetof(struct chacha_req, req) + |
551 | sizeof(struct ablkcipher_request) + | 551 | sizeof(struct skcipher_request) + |
552 | crypto_ablkcipher_reqsize(chacha), | 552 | crypto_skcipher_reqsize(chacha), |
553 | offsetof(struct poly_req, req) + | 553 | offsetof(struct poly_req, req) + |
554 | sizeof(struct ahash_request) + | 554 | sizeof(struct ahash_request) + |
555 | crypto_ahash_reqsize(poly))); | 555 | crypto_ahash_reqsize(poly))); |
@@ -562,7 +562,7 @@ static void chachapoly_exit(struct crypto_aead *tfm) | |||
562 | struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); | 562 | struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); |
563 | 563 | ||
564 | crypto_free_ahash(ctx->poly); | 564 | crypto_free_ahash(ctx->poly); |
565 | crypto_free_ablkcipher(ctx->chacha); | 565 | crypto_free_skcipher(ctx->chacha); |
566 | } | 566 | } |
567 | 567 | ||
568 | static void chachapoly_free(struct aead_instance *inst) | 568 | static void chachapoly_free(struct aead_instance *inst) |
@@ -579,7 +579,7 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb, | |||
579 | { | 579 | { |
580 | struct crypto_attr_type *algt; | 580 | struct crypto_attr_type *algt; |
581 | struct aead_instance *inst; | 581 | struct aead_instance *inst; |
582 | struct crypto_alg *chacha; | 582 | struct skcipher_alg *chacha; |
583 | struct crypto_alg *poly; | 583 | struct crypto_alg *poly; |
584 | struct hash_alg_common *poly_hash; | 584 | struct hash_alg_common *poly_hash; |
585 | struct chachapoly_instance_ctx *ctx; | 585 | struct chachapoly_instance_ctx *ctx; |
@@ -605,7 +605,9 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb, | |||
605 | 605 | ||
606 | poly = crypto_find_alg(poly_name, &crypto_ahash_type, | 606 | poly = crypto_find_alg(poly_name, &crypto_ahash_type, |
607 | CRYPTO_ALG_TYPE_HASH, | 607 | CRYPTO_ALG_TYPE_HASH, |
608 | CRYPTO_ALG_TYPE_AHASH_MASK); | 608 | CRYPTO_ALG_TYPE_AHASH_MASK | |
609 | crypto_requires_sync(algt->type, | ||
610 | algt->mask)); | ||
609 | if (IS_ERR(poly)) | 611 | if (IS_ERR(poly)) |
610 | return PTR_ERR(poly); | 612 | return PTR_ERR(poly); |
611 | 613 | ||
@@ -623,20 +625,20 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb, | |||
623 | goto err_free_inst; | 625 | goto err_free_inst; |
624 | 626 | ||
625 | crypto_set_skcipher_spawn(&ctx->chacha, aead_crypto_instance(inst)); | 627 | crypto_set_skcipher_spawn(&ctx->chacha, aead_crypto_instance(inst)); |
626 | err = crypto_grab_skcipher(&ctx->chacha, chacha_name, 0, | 628 | err = crypto_grab_skcipher2(&ctx->chacha, chacha_name, 0, |
627 | crypto_requires_sync(algt->type, | 629 | crypto_requires_sync(algt->type, |
628 | algt->mask)); | 630 | algt->mask)); |
629 | if (err) | 631 | if (err) |
630 | goto err_drop_poly; | 632 | goto err_drop_poly; |
631 | 633 | ||
632 | chacha = crypto_skcipher_spawn_alg(&ctx->chacha); | 634 | chacha = crypto_spawn_skcipher_alg(&ctx->chacha); |
633 | 635 | ||
634 | err = -EINVAL; | 636 | err = -EINVAL; |
635 | /* Need 16-byte IV size, including Initial Block Counter value */ | 637 | /* Need 16-byte IV size, including Initial Block Counter value */ |
636 | if (chacha->cra_ablkcipher.ivsize != CHACHA20_IV_SIZE) | 638 | if (crypto_skcipher_alg_ivsize(chacha) != CHACHA20_IV_SIZE) |
637 | goto out_drop_chacha; | 639 | goto out_drop_chacha; |
638 | /* Not a stream cipher? */ | 640 | /* Not a stream cipher? */ |
639 | if (chacha->cra_blocksize != 1) | 641 | if (chacha->base.cra_blocksize != 1) |
640 | goto out_drop_chacha; | 642 | goto out_drop_chacha; |
641 | 643 | ||
642 | err = -ENAMETOOLONG; | 644 | err = -ENAMETOOLONG; |
@@ -645,20 +647,21 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb, | |||
645 | poly_name) >= CRYPTO_MAX_ALG_NAME) | 647 | poly_name) >= CRYPTO_MAX_ALG_NAME) |
646 | goto out_drop_chacha; | 648 | goto out_drop_chacha; |
647 | if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, | 649 | if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
648 | "%s(%s,%s)", name, chacha->cra_driver_name, | 650 | "%s(%s,%s)", name, chacha->base.cra_driver_name, |
649 | poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) | 651 | poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) |
650 | goto out_drop_chacha; | 652 | goto out_drop_chacha; |
651 | 653 | ||
652 | inst->alg.base.cra_flags = (chacha->cra_flags | poly->cra_flags) & | 654 | inst->alg.base.cra_flags = (chacha->base.cra_flags | poly->cra_flags) & |
653 | CRYPTO_ALG_ASYNC; | 655 | CRYPTO_ALG_ASYNC; |
654 | inst->alg.base.cra_priority = (chacha->cra_priority + | 656 | inst->alg.base.cra_priority = (chacha->base.cra_priority + |
655 | poly->cra_priority) / 2; | 657 | poly->cra_priority) / 2; |
656 | inst->alg.base.cra_blocksize = 1; | 658 | inst->alg.base.cra_blocksize = 1; |
657 | inst->alg.base.cra_alignmask = chacha->cra_alignmask | | 659 | inst->alg.base.cra_alignmask = chacha->base.cra_alignmask | |
658 | poly->cra_alignmask; | 660 | poly->cra_alignmask; |
659 | inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) + | 661 | inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) + |
660 | ctx->saltlen; | 662 | ctx->saltlen; |
661 | inst->alg.ivsize = ivsize; | 663 | inst->alg.ivsize = ivsize; |
664 | inst->alg.chunksize = crypto_skcipher_alg_chunksize(chacha); | ||
662 | inst->alg.maxauthsize = POLY1305_DIGEST_SIZE; | 665 | inst->alg.maxauthsize = POLY1305_DIGEST_SIZE; |
663 | inst->alg.init = chachapoly_init; | 666 | inst->alg.init = chachapoly_init; |
664 | inst->alg.exit = chachapoly_exit; | 667 | inst->alg.exit = chachapoly_exit; |