diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2015-07-16 00:35:08 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-07-17 09:20:19 -0400 |
commit | 747909223397e11743c81352b3e4fdd29346bbf9 (patch) | |
tree | b1a309fac0c7fbb69e390b57bb10b5cc18099f1d /crypto/chacha20poly1305.c | |
parent | 6e8ec66c3d9cebcbf71d66f92e40b5d7e1d1f490 (diff) |
crypto: chacha20poly1305 - Convert to new AEAD interface
This patch converts rfc7539 and rfc7539esp to the new AEAD interface.
The test vectors for rfc7539esp have also been updated to include
the IV.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Tested-by: Martin Willi <martin@strongswan.org>
Diffstat (limited to 'crypto/chacha20poly1305.c')
-rw-r--r-- | crypto/chacha20poly1305.c | 213 |
1 files changed, 127 insertions, 86 deletions
diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c index 7b46ed799a64..86260937b0f3 100644 --- a/crypto/chacha20poly1305.c +++ b/crypto/chacha20poly1305.c | |||
@@ -60,12 +60,16 @@ struct chacha_req { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | struct chachapoly_req_ctx { | 62 | struct chachapoly_req_ctx { |
63 | struct scatterlist src[2]; | ||
64 | struct scatterlist dst[2]; | ||
63 | /* the key we generate for Poly1305 using Chacha20 */ | 65 | /* the key we generate for Poly1305 using Chacha20 */ |
64 | u8 key[POLY1305_KEY_SIZE]; | 66 | u8 key[POLY1305_KEY_SIZE]; |
65 | /* calculated Poly1305 tag */ | 67 | /* calculated Poly1305 tag */ |
66 | u8 tag[POLY1305_DIGEST_SIZE]; | 68 | u8 tag[POLY1305_DIGEST_SIZE]; |
67 | /* length of data to en/decrypt, without ICV */ | 69 | /* length of data to en/decrypt, without ICV */ |
68 | unsigned int cryptlen; | 70 | unsigned int cryptlen; |
71 | /* Actual AD, excluding IV */ | ||
72 | unsigned int assoclen; | ||
69 | union { | 73 | union { |
70 | struct poly_req poly; | 74 | struct poly_req poly; |
71 | struct chacha_req chacha; | 75 | struct chacha_req chacha; |
@@ -98,7 +102,9 @@ static int poly_verify_tag(struct aead_request *req) | |||
98 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); | 102 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); |
99 | u8 tag[sizeof(rctx->tag)]; | 103 | u8 tag[sizeof(rctx->tag)]; |
100 | 104 | ||
101 | scatterwalk_map_and_copy(tag, req->src, rctx->cryptlen, sizeof(tag), 0); | 105 | scatterwalk_map_and_copy(tag, req->src, |
106 | req->assoclen + rctx->cryptlen, | ||
107 | sizeof(tag), 0); | ||
102 | if (crypto_memneq(tag, rctx->tag, sizeof(tag))) | 108 | if (crypto_memneq(tag, rctx->tag, sizeof(tag))) |
103 | return -EBADMSG; | 109 | return -EBADMSG; |
104 | return 0; | 110 | return 0; |
@@ -108,7 +114,8 @@ static int poly_copy_tag(struct aead_request *req) | |||
108 | { | 114 | { |
109 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); | 115 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); |
110 | 116 | ||
111 | scatterwalk_map_and_copy(rctx->tag, req->dst, rctx->cryptlen, | 117 | scatterwalk_map_and_copy(rctx->tag, req->dst, |
118 | req->assoclen + rctx->cryptlen, | ||
112 | sizeof(rctx->tag), 1); | 119 | sizeof(rctx->tag), 1); |
113 | return 0; | 120 | return 0; |
114 | } | 121 | } |
@@ -123,14 +130,24 @@ static int chacha_decrypt(struct aead_request *req) | |||
123 | struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); | 130 | struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); |
124 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); | 131 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); |
125 | struct chacha_req *creq = &rctx->u.chacha; | 132 | struct chacha_req *creq = &rctx->u.chacha; |
133 | struct scatterlist *src, *dst; | ||
126 | int err; | 134 | int err; |
127 | 135 | ||
128 | chacha_iv(creq->iv, req, 1); | 136 | chacha_iv(creq->iv, req, 1); |
129 | 137 | ||
138 | sg_init_table(rctx->src, 2); | ||
139 | src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen); | ||
140 | dst = src; | ||
141 | |||
142 | if (req->src != req->dst) { | ||
143 | sg_init_table(rctx->dst, 2); | ||
144 | dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen); | ||
145 | } | ||
146 | |||
130 | ablkcipher_request_set_callback(&creq->req, aead_request_flags(req), | 147 | ablkcipher_request_set_callback(&creq->req, aead_request_flags(req), |
131 | chacha_decrypt_done, req); | 148 | chacha_decrypt_done, req); |
132 | ablkcipher_request_set_tfm(&creq->req, ctx->chacha); | 149 | ablkcipher_request_set_tfm(&creq->req, ctx->chacha); |
133 | ablkcipher_request_set_crypt(&creq->req, req->src, req->dst, | 150 | ablkcipher_request_set_crypt(&creq->req, src, dst, |
134 | rctx->cryptlen, creq->iv); | 151 | rctx->cryptlen, creq->iv); |
135 | err = crypto_ablkcipher_decrypt(&creq->req); | 152 | err = crypto_ablkcipher_decrypt(&creq->req); |
136 | if (err) | 153 | if (err) |
@@ -156,14 +173,15 @@ static void poly_tail_done(struct crypto_async_request *areq, int err) | |||
156 | 173 | ||
157 | static int poly_tail(struct aead_request *req) | 174 | static int poly_tail(struct aead_request *req) |
158 | { | 175 | { |
159 | struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); | 176 | struct crypto_aead *tfm = crypto_aead_reqtfm(req); |
177 | struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); | ||
160 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); | 178 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); |
161 | struct poly_req *preq = &rctx->u.poly; | 179 | struct poly_req *preq = &rctx->u.poly; |
162 | __le64 len; | 180 | __le64 len; |
163 | int err; | 181 | int err; |
164 | 182 | ||
165 | sg_init_table(preq->src, 1); | 183 | sg_init_table(preq->src, 1); |
166 | len = cpu_to_le64(req->assoclen); | 184 | len = cpu_to_le64(rctx->assoclen); |
167 | memcpy(&preq->tail.assoclen, &len, sizeof(len)); | 185 | memcpy(&preq->tail.assoclen, &len, sizeof(len)); |
168 | len = cpu_to_le64(rctx->cryptlen); | 186 | len = cpu_to_le64(rctx->cryptlen); |
169 | memcpy(&preq->tail.cryptlen, &len, sizeof(len)); | 187 | memcpy(&preq->tail.cryptlen, &len, sizeof(len)); |
@@ -228,6 +246,9 @@ static int poly_cipher(struct aead_request *req) | |||
228 | if (rctx->cryptlen == req->cryptlen) /* encrypting */ | 246 | if (rctx->cryptlen == req->cryptlen) /* encrypting */ |
229 | crypt = req->dst; | 247 | crypt = req->dst; |
230 | 248 | ||
249 | sg_init_table(rctx->src, 2); | ||
250 | crypt = scatterwalk_ffwd(rctx->src, crypt, req->assoclen); | ||
251 | |||
231 | ahash_request_set_callback(&preq->req, aead_request_flags(req), | 252 | ahash_request_set_callback(&preq->req, aead_request_flags(req), |
232 | poly_cipher_done, req); | 253 | poly_cipher_done, req); |
233 | ahash_request_set_tfm(&preq->req, ctx->poly); | 254 | ahash_request_set_tfm(&preq->req, ctx->poly); |
@@ -253,7 +274,7 @@ static int poly_adpad(struct aead_request *req) | |||
253 | unsigned int padlen, bs = POLY1305_BLOCK_SIZE; | 274 | unsigned int padlen, bs = POLY1305_BLOCK_SIZE; |
254 | int err; | 275 | int err; |
255 | 276 | ||
256 | padlen = (bs - (req->assoclen % bs)) % bs; | 277 | padlen = (bs - (rctx->assoclen % bs)) % bs; |
257 | memset(preq->pad, 0, sizeof(preq->pad)); | 278 | memset(preq->pad, 0, sizeof(preq->pad)); |
258 | sg_init_table(preq->src, 1); | 279 | sg_init_table(preq->src, 1); |
259 | sg_set_buf(preq->src, preq->pad, padlen); | 280 | sg_set_buf(preq->src, preq->pad, padlen); |
@@ -285,7 +306,7 @@ static int poly_ad(struct aead_request *req) | |||
285 | ahash_request_set_callback(&preq->req, aead_request_flags(req), | 306 | ahash_request_set_callback(&preq->req, aead_request_flags(req), |
286 | poly_ad_done, req); | 307 | poly_ad_done, req); |
287 | ahash_request_set_tfm(&preq->req, ctx->poly); | 308 | ahash_request_set_tfm(&preq->req, ctx->poly); |
288 | ahash_request_set_crypt(&preq->req, req->assoc, NULL, req->assoclen); | 309 | ahash_request_set_crypt(&preq->req, req->src, NULL, rctx->assoclen); |
289 | 310 | ||
290 | err = crypto_ahash_update(&preq->req); | 311 | err = crypto_ahash_update(&preq->req); |
291 | if (err) | 312 | if (err) |
@@ -351,11 +372,20 @@ static void poly_genkey_done(struct crypto_async_request *areq, int err) | |||
351 | 372 | ||
352 | static int poly_genkey(struct aead_request *req) | 373 | static int poly_genkey(struct aead_request *req) |
353 | { | 374 | { |
354 | struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); | 375 | struct crypto_aead *tfm = crypto_aead_reqtfm(req); |
376 | struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); | ||
355 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); | 377 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); |
356 | struct chacha_req *creq = &rctx->u.chacha; | 378 | struct chacha_req *creq = &rctx->u.chacha; |
357 | int err; | 379 | int err; |
358 | 380 | ||
381 | rctx->assoclen = req->assoclen; | ||
382 | |||
383 | if (crypto_aead_ivsize(tfm) == 8) { | ||
384 | if (rctx->assoclen < 8) | ||
385 | return -EINVAL; | ||
386 | rctx->assoclen -= 8; | ||
387 | } | ||
388 | |||
359 | sg_init_table(creq->src, 1); | 389 | sg_init_table(creq->src, 1); |
360 | memset(rctx->key, 0, sizeof(rctx->key)); | 390 | memset(rctx->key, 0, sizeof(rctx->key)); |
361 | sg_set_buf(creq->src, rctx->key, sizeof(rctx->key)); | 391 | sg_set_buf(creq->src, rctx->key, sizeof(rctx->key)); |
@@ -385,14 +415,24 @@ static int chacha_encrypt(struct aead_request *req) | |||
385 | struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); | 415 | struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); |
386 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); | 416 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); |
387 | struct chacha_req *creq = &rctx->u.chacha; | 417 | struct chacha_req *creq = &rctx->u.chacha; |
418 | struct scatterlist *src, *dst; | ||
388 | int err; | 419 | int err; |
389 | 420 | ||
390 | chacha_iv(creq->iv, req, 1); | 421 | chacha_iv(creq->iv, req, 1); |
391 | 422 | ||
423 | sg_init_table(rctx->src, 2); | ||
424 | src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen); | ||
425 | dst = src; | ||
426 | |||
427 | if (req->src != req->dst) { | ||
428 | sg_init_table(rctx->dst, 2); | ||
429 | dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen); | ||
430 | } | ||
431 | |||
392 | ablkcipher_request_set_callback(&creq->req, aead_request_flags(req), | 432 | ablkcipher_request_set_callback(&creq->req, aead_request_flags(req), |
393 | chacha_encrypt_done, req); | 433 | chacha_encrypt_done, req); |
394 | ablkcipher_request_set_tfm(&creq->req, ctx->chacha); | 434 | ablkcipher_request_set_tfm(&creq->req, ctx->chacha); |
395 | ablkcipher_request_set_crypt(&creq->req, req->src, req->dst, | 435 | ablkcipher_request_set_crypt(&creq->req, src, dst, |
396 | req->cryptlen, creq->iv); | 436 | req->cryptlen, creq->iv); |
397 | err = crypto_ablkcipher_encrypt(&creq->req); | 437 | err = crypto_ablkcipher_encrypt(&creq->req); |
398 | if (err) | 438 | if (err) |
@@ -426,8 +466,6 @@ static int chachapoly_decrypt(struct aead_request *req) | |||
426 | { | 466 | { |
427 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); | 467 | struct chachapoly_req_ctx *rctx = aead_request_ctx(req); |
428 | 468 | ||
429 | if (req->cryptlen < POLY1305_DIGEST_SIZE) | ||
430 | return -EINVAL; | ||
431 | rctx->cryptlen = req->cryptlen - POLY1305_DIGEST_SIZE; | 469 | rctx->cryptlen = req->cryptlen - POLY1305_DIGEST_SIZE; |
432 | 470 | ||
433 | /* decrypt call chain: | 471 | /* decrypt call chain: |
@@ -476,11 +514,11 @@ static int chachapoly_setauthsize(struct crypto_aead *tfm, | |||
476 | return 0; | 514 | return 0; |
477 | } | 515 | } |
478 | 516 | ||
479 | static int chachapoly_init(struct crypto_tfm *tfm) | 517 | static int chachapoly_init(struct crypto_aead *tfm) |
480 | { | 518 | { |
481 | struct crypto_instance *inst = (void *)tfm->__crt_alg; | 519 | struct aead_instance *inst = aead_alg_instance(tfm); |
482 | struct chachapoly_instance_ctx *ictx = crypto_instance_ctx(inst); | 520 | struct chachapoly_instance_ctx *ictx = aead_instance_ctx(inst); |
483 | struct chachapoly_ctx *ctx = crypto_tfm_ctx(tfm); | 521 | struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); |
484 | struct crypto_ablkcipher *chacha; | 522 | struct crypto_ablkcipher *chacha; |
485 | struct crypto_ahash *poly; | 523 | struct crypto_ahash *poly; |
486 | unsigned long align; | 524 | unsigned long align; |
@@ -499,77 +537,88 @@ static int chachapoly_init(struct crypto_tfm *tfm) | |||
499 | ctx->poly = poly; | 537 | ctx->poly = poly; |
500 | ctx->saltlen = ictx->saltlen; | 538 | ctx->saltlen = ictx->saltlen; |
501 | 539 | ||
502 | align = crypto_tfm_alg_alignmask(tfm); | 540 | align = crypto_aead_alignmask(tfm); |
503 | align &= ~(crypto_tfm_ctx_alignment() - 1); | 541 | align &= ~(crypto_tfm_ctx_alignment() - 1); |
504 | crypto_aead_set_reqsize(__crypto_aead_cast(tfm), | 542 | crypto_aead_set_reqsize( |
505 | align + offsetof(struct chachapoly_req_ctx, u) + | 543 | tfm, |
506 | max(offsetof(struct chacha_req, req) + | 544 | align + offsetof(struct chachapoly_req_ctx, u) + |
507 | sizeof(struct ablkcipher_request) + | 545 | max(offsetof(struct chacha_req, req) + |
508 | crypto_ablkcipher_reqsize(chacha), | 546 | sizeof(struct ablkcipher_request) + |
509 | offsetof(struct poly_req, req) + | 547 | crypto_ablkcipher_reqsize(chacha), |
510 | sizeof(struct ahash_request) + | 548 | offsetof(struct poly_req, req) + |
511 | crypto_ahash_reqsize(poly))); | 549 | sizeof(struct ahash_request) + |
550 | crypto_ahash_reqsize(poly))); | ||
512 | 551 | ||
513 | return 0; | 552 | return 0; |
514 | } | 553 | } |
515 | 554 | ||
516 | static void chachapoly_exit(struct crypto_tfm *tfm) | 555 | static void chachapoly_exit(struct crypto_aead *tfm) |
517 | { | 556 | { |
518 | struct chachapoly_ctx *ctx = crypto_tfm_ctx(tfm); | 557 | struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); |
519 | 558 | ||
520 | crypto_free_ahash(ctx->poly); | 559 | crypto_free_ahash(ctx->poly); |
521 | crypto_free_ablkcipher(ctx->chacha); | 560 | crypto_free_ablkcipher(ctx->chacha); |
522 | } | 561 | } |
523 | 562 | ||
524 | static struct crypto_instance *chachapoly_alloc(struct rtattr **tb, | 563 | static void chachapoly_free(struct aead_instance *inst) |
525 | const char *name, | 564 | { |
526 | unsigned int ivsize) | 565 | struct chachapoly_instance_ctx *ctx = aead_instance_ctx(inst); |
566 | |||
567 | crypto_drop_skcipher(&ctx->chacha); | ||
568 | crypto_drop_ahash(&ctx->poly); | ||
569 | kfree(inst); | ||
570 | } | ||
571 | |||
572 | static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb, | ||
573 | const char *name, unsigned int ivsize) | ||
527 | { | 574 | { |
528 | struct crypto_attr_type *algt; | 575 | struct crypto_attr_type *algt; |
529 | struct crypto_instance *inst; | 576 | struct aead_instance *inst; |
530 | struct crypto_alg *chacha; | 577 | struct crypto_alg *chacha; |
531 | struct crypto_alg *poly; | 578 | struct crypto_alg *poly; |
532 | struct ahash_alg *poly_ahash; | 579 | struct hash_alg_common *poly_hash; |
533 | struct chachapoly_instance_ctx *ctx; | 580 | struct chachapoly_instance_ctx *ctx; |
534 | const char *chacha_name, *poly_name; | 581 | const char *chacha_name, *poly_name; |
535 | int err; | 582 | int err; |
536 | 583 | ||
537 | if (ivsize > CHACHAPOLY_IV_SIZE) | 584 | if (ivsize > CHACHAPOLY_IV_SIZE) |
538 | return ERR_PTR(-EINVAL); | 585 | return -EINVAL; |
539 | 586 | ||
540 | algt = crypto_get_attr_type(tb); | 587 | algt = crypto_get_attr_type(tb); |
541 | if (IS_ERR(algt)) | 588 | if (IS_ERR(algt)) |
542 | return ERR_CAST(algt); | 589 | return PTR_ERR(algt); |
543 | 590 | ||
544 | if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) | 591 | if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_AEAD_NEW)) & |
545 | return ERR_PTR(-EINVAL); | 592 | algt->mask) |
593 | return -EINVAL; | ||
546 | 594 | ||
547 | chacha_name = crypto_attr_alg_name(tb[1]); | 595 | chacha_name = crypto_attr_alg_name(tb[1]); |
548 | if (IS_ERR(chacha_name)) | 596 | if (IS_ERR(chacha_name)) |
549 | return ERR_CAST(chacha_name); | 597 | return PTR_ERR(chacha_name); |
550 | poly_name = crypto_attr_alg_name(tb[2]); | 598 | poly_name = crypto_attr_alg_name(tb[2]); |
551 | if (IS_ERR(poly_name)) | 599 | if (IS_ERR(poly_name)) |
552 | return ERR_CAST(poly_name); | 600 | return PTR_ERR(poly_name); |
553 | 601 | ||
554 | poly = crypto_find_alg(poly_name, &crypto_ahash_type, | 602 | poly = crypto_find_alg(poly_name, &crypto_ahash_type, |
555 | CRYPTO_ALG_TYPE_HASH, | 603 | CRYPTO_ALG_TYPE_HASH, |
556 | CRYPTO_ALG_TYPE_AHASH_MASK); | 604 | CRYPTO_ALG_TYPE_AHASH_MASK); |
557 | if (IS_ERR(poly)) | 605 | if (IS_ERR(poly)) |
558 | return ERR_CAST(poly); | 606 | return PTR_ERR(poly); |
559 | 607 | ||
560 | err = -ENOMEM; | 608 | err = -ENOMEM; |
561 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); | 609 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); |
562 | if (!inst) | 610 | if (!inst) |
563 | goto out_put_poly; | 611 | goto out_put_poly; |
564 | 612 | ||
565 | ctx = crypto_instance_ctx(inst); | 613 | ctx = aead_instance_ctx(inst); |
566 | ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize; | 614 | ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize; |
567 | poly_ahash = container_of(poly, struct ahash_alg, halg.base); | 615 | poly_hash = __crypto_hash_alg_common(poly); |
568 | err = crypto_init_ahash_spawn(&ctx->poly, &poly_ahash->halg, inst); | 616 | err = crypto_init_ahash_spawn(&ctx->poly, poly_hash, |
617 | aead_crypto_instance(inst)); | ||
569 | if (err) | 618 | if (err) |
570 | goto err_free_inst; | 619 | goto err_free_inst; |
571 | 620 | ||
572 | crypto_set_skcipher_spawn(&ctx->chacha, inst); | 621 | crypto_set_skcipher_spawn(&ctx->chacha, aead_crypto_instance(inst)); |
573 | err = crypto_grab_skcipher(&ctx->chacha, chacha_name, 0, | 622 | err = crypto_grab_skcipher(&ctx->chacha, chacha_name, 0, |
574 | crypto_requires_sync(algt->type, | 623 | crypto_requires_sync(algt->type, |
575 | algt->mask)); | 624 | algt->mask)); |
@@ -587,37 +636,43 @@ static struct crypto_instance *chachapoly_alloc(struct rtattr **tb, | |||
587 | goto out_drop_chacha; | 636 | goto out_drop_chacha; |
588 | 637 | ||
589 | err = -ENAMETOOLONG; | 638 | err = -ENAMETOOLONG; |
590 | if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, | 639 | if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, |
591 | "%s(%s,%s)", name, chacha_name, | 640 | "%s(%s,%s)", name, chacha_name, |
592 | poly_name) >= CRYPTO_MAX_ALG_NAME) | 641 | poly_name) >= CRYPTO_MAX_ALG_NAME) |
593 | goto out_drop_chacha; | 642 | goto out_drop_chacha; |
594 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, | 643 | if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
595 | "%s(%s,%s)", name, chacha->cra_driver_name, | 644 | "%s(%s,%s)", name, chacha->cra_driver_name, |
596 | poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) | 645 | poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) |
597 | goto out_drop_chacha; | 646 | goto out_drop_chacha; |
598 | 647 | ||
599 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; | 648 | inst->alg.base.cra_flags = (chacha->cra_flags | poly->cra_flags) & |
600 | inst->alg.cra_flags |= (chacha->cra_flags | | 649 | CRYPTO_ALG_ASYNC; |
601 | poly->cra_flags) & CRYPTO_ALG_ASYNC; | 650 | inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW; |
602 | inst->alg.cra_priority = (chacha->cra_priority + | 651 | inst->alg.base.cra_priority = (chacha->cra_priority + |
603 | poly->cra_priority) / 2; | 652 | poly->cra_priority) / 2; |
604 | inst->alg.cra_blocksize = 1; | 653 | inst->alg.base.cra_blocksize = 1; |
605 | inst->alg.cra_alignmask = chacha->cra_alignmask | poly->cra_alignmask; | 654 | inst->alg.base.cra_alignmask = chacha->cra_alignmask | |
606 | inst->alg.cra_type = &crypto_nivaead_type; | 655 | poly->cra_alignmask; |
607 | inst->alg.cra_aead.ivsize = ivsize; | 656 | inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) + |
608 | inst->alg.cra_aead.maxauthsize = POLY1305_DIGEST_SIZE; | 657 | ctx->saltlen; |
609 | inst->alg.cra_ctxsize = sizeof(struct chachapoly_ctx) + ctx->saltlen; | 658 | inst->alg.ivsize = ivsize; |
610 | inst->alg.cra_init = chachapoly_init; | 659 | inst->alg.maxauthsize = POLY1305_DIGEST_SIZE; |
611 | inst->alg.cra_exit = chachapoly_exit; | 660 | inst->alg.init = chachapoly_init; |
612 | inst->alg.cra_aead.encrypt = chachapoly_encrypt; | 661 | inst->alg.exit = chachapoly_exit; |
613 | inst->alg.cra_aead.decrypt = chachapoly_decrypt; | 662 | inst->alg.encrypt = chachapoly_encrypt; |
614 | inst->alg.cra_aead.setkey = chachapoly_setkey; | 663 | inst->alg.decrypt = chachapoly_decrypt; |
615 | inst->alg.cra_aead.setauthsize = chachapoly_setauthsize; | 664 | inst->alg.setkey = chachapoly_setkey; |
616 | inst->alg.cra_aead.geniv = "seqiv"; | 665 | inst->alg.setauthsize = chachapoly_setauthsize; |
617 | 666 | ||
618 | out: | 667 | inst->free = chachapoly_free; |
668 | |||
669 | err = aead_register_instance(tmpl, inst); | ||
670 | if (err) | ||
671 | goto out_drop_chacha; | ||
672 | |||
673 | out_put_poly: | ||
619 | crypto_mod_put(poly); | 674 | crypto_mod_put(poly); |
620 | return inst; | 675 | return err; |
621 | 676 | ||
622 | out_drop_chacha: | 677 | out_drop_chacha: |
623 | crypto_drop_skcipher(&ctx->chacha); | 678 | crypto_drop_skcipher(&ctx->chacha); |
@@ -625,41 +680,28 @@ err_drop_poly: | |||
625 | crypto_drop_ahash(&ctx->poly); | 680 | crypto_drop_ahash(&ctx->poly); |
626 | err_free_inst: | 681 | err_free_inst: |
627 | kfree(inst); | 682 | kfree(inst); |
628 | out_put_poly: | 683 | goto out_put_poly; |
629 | inst = ERR_PTR(err); | ||
630 | goto out; | ||
631 | } | ||
632 | |||
633 | static struct crypto_instance *rfc7539_alloc(struct rtattr **tb) | ||
634 | { | ||
635 | return chachapoly_alloc(tb, "rfc7539", 12); | ||
636 | } | 684 | } |
637 | 685 | ||
638 | static struct crypto_instance *rfc7539esp_alloc(struct rtattr **tb) | 686 | static int rfc7539_create(struct crypto_template *tmpl, struct rtattr **tb) |
639 | { | 687 | { |
640 | return chachapoly_alloc(tb, "rfc7539esp", 8); | 688 | return chachapoly_create(tmpl, tb, "rfc7539", 12); |
641 | } | 689 | } |
642 | 690 | ||
643 | static void chachapoly_free(struct crypto_instance *inst) | 691 | static int rfc7539esp_create(struct crypto_template *tmpl, struct rtattr **tb) |
644 | { | 692 | { |
645 | struct chachapoly_instance_ctx *ctx = crypto_instance_ctx(inst); | 693 | return chachapoly_create(tmpl, tb, "rfc7539esp", 8); |
646 | |||
647 | crypto_drop_skcipher(&ctx->chacha); | ||
648 | crypto_drop_ahash(&ctx->poly); | ||
649 | kfree(inst); | ||
650 | } | 694 | } |
651 | 695 | ||
652 | static struct crypto_template rfc7539_tmpl = { | 696 | static struct crypto_template rfc7539_tmpl = { |
653 | .name = "rfc7539", | 697 | .name = "rfc7539", |
654 | .alloc = rfc7539_alloc, | 698 | .create = rfc7539_create, |
655 | .free = chachapoly_free, | ||
656 | .module = THIS_MODULE, | 699 | .module = THIS_MODULE, |
657 | }; | 700 | }; |
658 | 701 | ||
659 | static struct crypto_template rfc7539esp_tmpl = { | 702 | static struct crypto_template rfc7539esp_tmpl = { |
660 | .name = "rfc7539esp", | 703 | .name = "rfc7539esp", |
661 | .alloc = rfc7539esp_alloc, | 704 | .create = rfc7539esp_create, |
662 | .free = chachapoly_free, | ||
663 | .module = THIS_MODULE, | 705 | .module = THIS_MODULE, |
664 | }; | 706 | }; |
665 | 707 | ||
@@ -690,6 +732,5 @@ module_exit(chacha20poly1305_module_exit); | |||
690 | MODULE_LICENSE("GPL"); | 732 | MODULE_LICENSE("GPL"); |
691 | MODULE_AUTHOR("Martin Willi <martin@strongswan.org>"); | 733 | MODULE_AUTHOR("Martin Willi <martin@strongswan.org>"); |
692 | MODULE_DESCRIPTION("ChaCha20-Poly1305 AEAD"); | 734 | MODULE_DESCRIPTION("ChaCha20-Poly1305 AEAD"); |
693 | MODULE_ALIAS_CRYPTO("chacha20poly1305"); | ||
694 | MODULE_ALIAS_CRYPTO("rfc7539"); | 735 | MODULE_ALIAS_CRYPTO("rfc7539"); |
695 | MODULE_ALIAS_CRYPTO("rfc7539esp"); | 736 | MODULE_ALIAS_CRYPTO("rfc7539esp"); |