summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2016-07-12 01:17:40 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2016-07-18 05:35:41 -0400
commit1e1f006112b50640d7fc11851346f906d223df09 (patch)
treeb2bfcc3cc716d88628b8b7561e98791162aa27b1 /crypto
parent16f37ecdd068884fc4f4177f83ac77910f4fc113 (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.c89
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
33struct chachapoly_ctx { 33struct 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 {
53struct chacha_req { 53struct 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
59struct chachapoly_req_ctx { 59struct 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
568static void chachapoly_free(struct aead_instance *inst) 568static 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;