1 /* 2 * ChaCha20-Poly1305 AEAD, RFC7539 3 * 4 * Copyright (C) 2015 Martin Willi 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12 #include <crypto/internal/aead.h> 13 #include <crypto/internal/hash.h> 14 #include <crypto/internal/skcipher.h> 15 #include <crypto/scatterwalk.h> 16 #include <crypto/chacha.h> 17 #include <crypto/poly1305.h> 18 #include <linux/err.h> 19 #include <linux/init.h> 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 23 #include "internal.h" 24 25 struct chachapoly_instance_ctx { 26 struct crypto_skcipher_spawn chacha; 27 struct crypto_ahash_spawn poly; 28 unsigned int saltlen; 29 }; 30 31 struct chachapoly_ctx { 32 struct crypto_skcipher *chacha; 33 struct crypto_ahash *poly; 34 /* key bytes we use for the ChaCha20 IV */ 35 unsigned int saltlen; 36 u8 salt[]; 37 }; 38 39 struct poly_req { 40 /* zero byte padding for AD/ciphertext, as needed */ 41 u8 pad[POLY1305_BLOCK_SIZE]; 42 /* tail data with AD/ciphertext lengths */ 43 struct { 44 __le64 assoclen; 45 __le64 cryptlen; 46 } tail; 47 struct scatterlist src[1]; 48 struct ahash_request req; /* must be last member */ 49 }; 50 51 struct chacha_req { 52 u8 iv[CHACHA_IV_SIZE]; 53 struct scatterlist src[1]; 54 struct skcipher_request req; /* must be last member */ 55 }; 56 57 struct chachapoly_req_ctx { 58 struct scatterlist src[2]; 59 struct scatterlist dst[2]; 60 /* the key we generate for Poly1305 using Chacha20 */ 61 u8 key[POLY1305_KEY_SIZE]; 62 /* calculated Poly1305 tag */ 63 u8 tag[POLY1305_DIGEST_SIZE]; 64 /* length of data to en/decrypt, without ICV */ 65 unsigned int cryptlen; 66 /* Actual AD, excluding IV */ 67 unsigned int assoclen; 68 union { 69 struct poly_req poly; 70 struct chacha_req chacha; 71 } u; 72 }; 73 74 static inline void async_done_continue(struct aead_request *req, int err, 75 int (*cont)(struct aead_request *)) 76 { 77 if (!err) 78 err = cont(req); 79 80 if (err != -EINPROGRESS && err != -EBUSY) 81 aead_request_complete(req, err); 82 } 83 84 static void chacha_iv(u8 *iv, struct aead_request *req, u32 icb) 85 { 86 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 87 __le32 leicb = cpu_to_le32(icb); 88 89 memcpy(iv, &leicb, sizeof(leicb)); 90 memcpy(iv + sizeof(leicb), ctx->salt, ctx->saltlen); 91 memcpy(iv + sizeof(leicb) + ctx->saltlen, req->iv, 92 CHACHA_IV_SIZE - sizeof(leicb) - ctx->saltlen); 93 } 94 95 static int poly_verify_tag(struct aead_request *req) 96 { 97 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 98 u8 tag[sizeof(rctx->tag)]; 99 100 scatterwalk_map_and_copy(tag, req->src, 101 req->assoclen + rctx->cryptlen, 102 sizeof(tag), 0); 103 if (crypto_memneq(tag, rctx->tag, sizeof(tag))) 104 return -EBADMSG; 105 return 0; 106 } 107 108 static int poly_copy_tag(struct aead_request *req) 109 { 110 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 111 112 scatterwalk_map_and_copy(rctx->tag, req->dst, 113 req->assoclen + rctx->cryptlen, 114 sizeof(rctx->tag), 1); 115 return 0; 116 } 117 118 static void chacha_decrypt_done(struct crypto_async_request *areq, int err) 119 { 120 async_done_continue(areq->data, err, poly_verify_tag); 121 } 122 123 static int chacha_decrypt(struct aead_request *req) 124 { 125 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 126 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 127 struct chacha_req *creq = &rctx->u.chacha; 128 struct scatterlist *src, *dst; 129 int err; 130 131 if (rctx->cryptlen == 0) 132 goto skip; 133 134 chacha_iv(creq->iv, req, 1); 135 136 sg_init_table(rctx->src, 2); 137 src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen); 138 dst = src; 139 140 if (req->src != req->dst) { 141 sg_init_table(rctx->dst, 2); 142 dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen); 143 } 144 145 skcipher_request_set_callback(&creq->req, aead_request_flags(req), 146 chacha_decrypt_done, req); 147 skcipher_request_set_tfm(&creq->req, ctx->chacha); 148 skcipher_request_set_crypt(&creq->req, src, dst, 149 rctx->cryptlen, creq->iv); 150 err = crypto_skcipher_decrypt(&creq->req); 151 if (err) 152 return err; 153 154 skip: 155 return poly_verify_tag(req); 156 } 157 158 static int poly_tail_continue(struct aead_request *req) 159 { 160 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 161 162 if (rctx->cryptlen == req->cryptlen) /* encrypting */ 163 return poly_copy_tag(req); 164 165 return chacha_decrypt(req); 166 } 167 168 static void poly_tail_done(struct crypto_async_request *areq, int err) 169 { 170 async_done_continue(areq->data, err, poly_tail_continue); 171 } 172 173 static int poly_tail(struct aead_request *req) 174 { 175 struct crypto_aead *tfm = crypto_aead_reqtfm(req); 176 struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); 177 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 178 struct poly_req *preq = &rctx->u.poly; 179 __le64 len; 180 int err; 181 182 sg_init_table(preq->src, 1); 183 len = cpu_to_le64(rctx->assoclen); 184 memcpy(&preq->tail.assoclen, &len, sizeof(len)); 185 len = cpu_to_le64(rctx->cryptlen); 186 memcpy(&preq->tail.cryptlen, &len, sizeof(len)); 187 sg_set_buf(preq->src, &preq->tail, sizeof(preq->tail)); 188 189 ahash_request_set_callback(&preq->req, aead_request_flags(req), 190 poly_tail_done, req); 191 ahash_request_set_tfm(&preq->req, ctx->poly); 192 ahash_request_set_crypt(&preq->req, preq->src, 193 rctx->tag, sizeof(preq->tail)); 194 195 err = crypto_ahash_finup(&preq->req); 196 if (err) 197 return err; 198 199 return poly_tail_continue(req); 200 } 201 202 static void poly_cipherpad_done(struct crypto_async_request *areq, int err) 203 { 204 async_done_continue(areq->data, err, poly_tail); 205 } 206 207 static int poly_cipherpad(struct aead_request *req) 208 { 209 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 210 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 211 struct poly_req *preq = &rctx->u.poly; 212 unsigned int padlen, bs = POLY1305_BLOCK_SIZE; 213 int err; 214 215 padlen = (bs - (rctx->cryptlen % bs)) % bs; 216 memset(preq->pad, 0, sizeof(preq->pad)); 217 sg_init_table(preq->src, 1); 218 sg_set_buf(preq->src, &preq->pad, padlen); 219 220 ahash_request_set_callback(&preq->req, aead_request_flags(req), 221 poly_cipherpad_done, req); 222 ahash_request_set_tfm(&preq->req, ctx->poly); 223 ahash_request_set_crypt(&preq->req, preq->src, NULL, padlen); 224 225 err = crypto_ahash_update(&preq->req); 226 if (err) 227 return err; 228 229 return poly_tail(req); 230 } 231 232 static void poly_cipher_done(struct crypto_async_request *areq, int err) 233 { 234 async_done_continue(areq->data, err, poly_cipherpad); 235 } 236 237 static int poly_cipher(struct aead_request *req) 238 { 239 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 240 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 241 struct poly_req *preq = &rctx->u.poly; 242 struct scatterlist *crypt = req->src; 243 int err; 244 245 if (rctx->cryptlen == req->cryptlen) /* encrypting */ 246 crypt = req->dst; 247 248 sg_init_table(rctx->src, 2); 249 crypt = scatterwalk_ffwd(rctx->src, crypt, req->assoclen); 250 251 ahash_request_set_callback(&preq->req, aead_request_flags(req), 252 poly_cipher_done, req); 253 ahash_request_set_tfm(&preq->req, ctx->poly); 254 ahash_request_set_crypt(&preq->req, crypt, NULL, rctx->cryptlen); 255 256 err = crypto_ahash_update(&preq->req); 257 if (err) 258 return err; 259 260 return poly_cipherpad(req); 261 } 262 263 static void poly_adpad_done(struct crypto_async_request *areq, int err) 264 { 265 async_done_continue(areq->data, err, poly_cipher); 266 } 267 268 static int poly_adpad(struct aead_request *req) 269 { 270 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 271 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 272 struct poly_req *preq = &rctx->u.poly; 273 unsigned int padlen, bs = POLY1305_BLOCK_SIZE; 274 int err; 275 276 padlen = (bs - (rctx->assoclen % bs)) % bs; 277 memset(preq->pad, 0, sizeof(preq->pad)); 278 sg_init_table(preq->src, 1); 279 sg_set_buf(preq->src, preq->pad, padlen); 280 281 ahash_request_set_callback(&preq->req, aead_request_flags(req), 282 poly_adpad_done, req); 283 ahash_request_set_tfm(&preq->req, ctx->poly); 284 ahash_request_set_crypt(&preq->req, preq->src, NULL, padlen); 285 286 err = crypto_ahash_update(&preq->req); 287 if (err) 288 return err; 289 290 return poly_cipher(req); 291 } 292 293 static void poly_ad_done(struct crypto_async_request *areq, int err) 294 { 295 async_done_continue(areq->data, err, poly_adpad); 296 } 297 298 static int poly_ad(struct aead_request *req) 299 { 300 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 301 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 302 struct poly_req *preq = &rctx->u.poly; 303 int err; 304 305 ahash_request_set_callback(&preq->req, aead_request_flags(req), 306 poly_ad_done, req); 307 ahash_request_set_tfm(&preq->req, ctx->poly); 308 ahash_request_set_crypt(&preq->req, req->src, NULL, rctx->assoclen); 309 310 err = crypto_ahash_update(&preq->req); 311 if (err) 312 return err; 313 314 return poly_adpad(req); 315 } 316 317 static void poly_setkey_done(struct crypto_async_request *areq, int err) 318 { 319 async_done_continue(areq->data, err, poly_ad); 320 } 321 322 static int poly_setkey(struct aead_request *req) 323 { 324 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 325 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 326 struct poly_req *preq = &rctx->u.poly; 327 int err; 328 329 sg_init_table(preq->src, 1); 330 sg_set_buf(preq->src, rctx->key, sizeof(rctx->key)); 331 332 ahash_request_set_callback(&preq->req, aead_request_flags(req), 333 poly_setkey_done, req); 334 ahash_request_set_tfm(&preq->req, ctx->poly); 335 ahash_request_set_crypt(&preq->req, preq->src, NULL, sizeof(rctx->key)); 336 337 err = crypto_ahash_update(&preq->req); 338 if (err) 339 return err; 340 341 return poly_ad(req); 342 } 343 344 static void poly_init_done(struct crypto_async_request *areq, int err) 345 { 346 async_done_continue(areq->data, err, poly_setkey); 347 } 348 349 static int poly_init(struct aead_request *req) 350 { 351 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 352 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 353 struct poly_req *preq = &rctx->u.poly; 354 int err; 355 356 ahash_request_set_callback(&preq->req, aead_request_flags(req), 357 poly_init_done, req); 358 ahash_request_set_tfm(&preq->req, ctx->poly); 359 360 err = crypto_ahash_init(&preq->req); 361 if (err) 362 return err; 363 364 return poly_setkey(req); 365 } 366 367 static void poly_genkey_done(struct crypto_async_request *areq, int err) 368 { 369 async_done_continue(areq->data, err, poly_init); 370 } 371 372 static int poly_genkey(struct aead_request *req) 373 { 374 struct crypto_aead *tfm = crypto_aead_reqtfm(req); 375 struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); 376 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 377 struct chacha_req *creq = &rctx->u.chacha; 378 int err; 379 380 rctx->assoclen = req->assoclen; 381 382 if (crypto_aead_ivsize(tfm) == 8) { 383 if (rctx->assoclen < 8) 384 return -EINVAL; 385 rctx->assoclen -= 8; 386 } 387 388 sg_init_table(creq->src, 1); 389 memset(rctx->key, 0, sizeof(rctx->key)); 390 sg_set_buf(creq->src, rctx->key, sizeof(rctx->key)); 391 392 chacha_iv(creq->iv, req, 0); 393 394 skcipher_request_set_callback(&creq->req, aead_request_flags(req), 395 poly_genkey_done, req); 396 skcipher_request_set_tfm(&creq->req, ctx->chacha); 397 skcipher_request_set_crypt(&creq->req, creq->src, creq->src, 398 POLY1305_KEY_SIZE, creq->iv); 399 400 err = crypto_skcipher_decrypt(&creq->req); 401 if (err) 402 return err; 403 404 return poly_init(req); 405 } 406 407 static void chacha_encrypt_done(struct crypto_async_request *areq, int err) 408 { 409 async_done_continue(areq->data, err, poly_genkey); 410 } 411 412 static int chacha_encrypt(struct aead_request *req) 413 { 414 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 415 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 416 struct chacha_req *creq = &rctx->u.chacha; 417 struct scatterlist *src, *dst; 418 int err; 419 420 if (req->cryptlen == 0) 421 goto skip; 422 423 chacha_iv(creq->iv, req, 1); 424 425 sg_init_table(rctx->src, 2); 426 src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen); 427 dst = src; 428 429 if (req->src != req->dst) { 430 sg_init_table(rctx->dst, 2); 431 dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen); 432 } 433 434 skcipher_request_set_callback(&creq->req, aead_request_flags(req), 435 chacha_encrypt_done, req); 436 skcipher_request_set_tfm(&creq->req, ctx->chacha); 437 skcipher_request_set_crypt(&creq->req, src, dst, 438 req->cryptlen, creq->iv); 439 err = crypto_skcipher_encrypt(&creq->req); 440 if (err) 441 return err; 442 443 skip: 444 return poly_genkey(req); 445 } 446 447 static int chachapoly_encrypt(struct aead_request *req) 448 { 449 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 450 451 rctx->cryptlen = req->cryptlen; 452 453 /* encrypt call chain: 454 * - chacha_encrypt/done() 455 * - poly_genkey/done() 456 * - poly_init/done() 457 * - poly_setkey/done() 458 * - poly_ad/done() 459 * - poly_adpad/done() 460 * - poly_cipher/done() 461 * - poly_cipherpad/done() 462 * - poly_tail/done/continue() 463 * - poly_copy_tag() 464 */ 465 return chacha_encrypt(req); 466 } 467 468 static int chachapoly_decrypt(struct aead_request *req) 469 { 470 struct chachapoly_req_ctx *rctx = aead_request_ctx(req); 471 472 rctx->cryptlen = req->cryptlen - POLY1305_DIGEST_SIZE; 473 474 /* decrypt call chain: 475 * - poly_genkey/done() 476 * - poly_init/done() 477 * - poly_setkey/done() 478 * - poly_ad/done() 479 * - poly_adpad/done() 480 * - poly_cipher/done() 481 * - poly_cipherpad/done() 482 * - poly_tail/done/continue() 483 * - chacha_decrypt/done() 484 * - poly_verify_tag() 485 */ 486 return poly_genkey(req); 487 } 488 489 static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, 490 unsigned int keylen) 491 { 492 struct chachapoly_ctx *ctx = crypto_aead_ctx(aead); 493 int err; 494 495 if (keylen != ctx->saltlen + CHACHA_KEY_SIZE) 496 return -EINVAL; 497 498 keylen -= ctx->saltlen; 499 memcpy(ctx->salt, key + keylen, ctx->saltlen); 500 501 crypto_skcipher_clear_flags(ctx->chacha, CRYPTO_TFM_REQ_MASK); 502 crypto_skcipher_set_flags(ctx->chacha, crypto_aead_get_flags(aead) & 503 CRYPTO_TFM_REQ_MASK); 504 505 err = crypto_skcipher_setkey(ctx->chacha, key, keylen); 506 crypto_aead_set_flags(aead, crypto_skcipher_get_flags(ctx->chacha) & 507 CRYPTO_TFM_RES_MASK); 508 return err; 509 } 510 511 static int chachapoly_setauthsize(struct crypto_aead *tfm, 512 unsigned int authsize) 513 { 514 if (authsize != POLY1305_DIGEST_SIZE) 515 return -EINVAL; 516 517 return 0; 518 } 519 520 static int chachapoly_init(struct crypto_aead *tfm) 521 { 522 struct aead_instance *inst = aead_alg_instance(tfm); 523 struct chachapoly_instance_ctx *ictx = aead_instance_ctx(inst); 524 struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); 525 struct crypto_skcipher *chacha; 526 struct crypto_ahash *poly; 527 unsigned long align; 528 529 poly = crypto_spawn_ahash(&ictx->poly); 530 if (IS_ERR(poly)) 531 return PTR_ERR(poly); 532 533 chacha = crypto_spawn_skcipher(&ictx->chacha); 534 if (IS_ERR(chacha)) { 535 crypto_free_ahash(poly); 536 return PTR_ERR(chacha); 537 } 538 539 ctx->chacha = chacha; 540 ctx->poly = poly; 541 ctx->saltlen = ictx->saltlen; 542 543 align = crypto_aead_alignmask(tfm); 544 align &= ~(crypto_tfm_ctx_alignment() - 1); 545 crypto_aead_set_reqsize( 546 tfm, 547 align + offsetof(struct chachapoly_req_ctx, u) + 548 max(offsetof(struct chacha_req, req) + 549 sizeof(struct skcipher_request) + 550 crypto_skcipher_reqsize(chacha), 551 offsetof(struct poly_req, req) + 552 sizeof(struct ahash_request) + 553 crypto_ahash_reqsize(poly))); 554 555 return 0; 556 } 557 558 static void chachapoly_exit(struct crypto_aead *tfm) 559 { 560 struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm); 561 562 crypto_free_ahash(ctx->poly); 563 crypto_free_skcipher(ctx->chacha); 564 } 565 566 static void chachapoly_free(struct aead_instance *inst) 567 { 568 struct chachapoly_instance_ctx *ctx = aead_instance_ctx(inst); 569 570 crypto_drop_skcipher(&ctx->chacha); 571 crypto_drop_ahash(&ctx->poly); 572 kfree(inst); 573 } 574 575 static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb, 576 const char *name, unsigned int ivsize) 577 { 578 struct crypto_attr_type *algt; 579 struct aead_instance *inst; 580 struct skcipher_alg *chacha; 581 struct crypto_alg *poly; 582 struct hash_alg_common *poly_hash; 583 struct chachapoly_instance_ctx *ctx; 584 const char *chacha_name, *poly_name; 585 int err; 586 587 if (ivsize > CHACHAPOLY_IV_SIZE) 588 return -EINVAL; 589 590 algt = crypto_get_attr_type(tb); 591 if (IS_ERR(algt)) 592 return PTR_ERR(algt); 593 594 if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) 595 return -EINVAL; 596 597 chacha_name = crypto_attr_alg_name(tb[1]); 598 if (IS_ERR(chacha_name)) 599 return PTR_ERR(chacha_name); 600 poly_name = crypto_attr_alg_name(tb[2]); 601 if (IS_ERR(poly_name)) 602 return PTR_ERR(poly_name); 603 604 poly = crypto_find_alg(poly_name, &crypto_ahash_type, 605 CRYPTO_ALG_TYPE_HASH, 606 CRYPTO_ALG_TYPE_AHASH_MASK | 607 crypto_requires_sync(algt->type, 608 algt->mask)); 609 if (IS_ERR(poly)) 610 return PTR_ERR(poly); 611 poly_hash = __crypto_hash_alg_common(poly); 612 613 err = -EINVAL; 614 if (poly_hash->digestsize != POLY1305_DIGEST_SIZE) 615 goto out_put_poly; 616 617 err = -ENOMEM; 618 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); 619 if (!inst) 620 goto out_put_poly; 621 622 ctx = aead_instance_ctx(inst); 623 ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize; 624 err = crypto_init_ahash_spawn(&ctx->poly, poly_hash, 625 aead_crypto_instance(inst)); 626 if (err) 627 goto err_free_inst; 628 629 crypto_set_skcipher_spawn(&ctx->chacha, aead_crypto_instance(inst)); 630 err = crypto_grab_skcipher(&ctx->chacha, chacha_name, 0, 631 crypto_requires_sync(algt->type, 632 algt->mask)); 633 if (err) 634 goto err_drop_poly; 635 636 chacha = crypto_spawn_skcipher_alg(&ctx->chacha); 637 638 err = -EINVAL; 639 /* Need 16-byte IV size, including Initial Block Counter value */ 640 if (crypto_skcipher_alg_ivsize(chacha) != CHACHA_IV_SIZE) 641 goto out_drop_chacha; 642 /* Not a stream cipher? */ 643 if (chacha->base.cra_blocksize != 1) 644 goto out_drop_chacha; 645 646 err = -ENAMETOOLONG; 647 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, 648 "%s(%s,%s)", name, chacha->base.cra_name, 649 poly->cra_name) >= CRYPTO_MAX_ALG_NAME) 650 goto out_drop_chacha; 651 if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, 652 "%s(%s,%s)", name, chacha->base.cra_driver_name, 653 poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 654 goto out_drop_chacha; 655 656 inst->alg.base.cra_flags = (chacha->base.cra_flags | poly->cra_flags) & 657 CRYPTO_ALG_ASYNC; 658 inst->alg.base.cra_priority = (chacha->base.cra_priority + 659 poly->cra_priority) / 2; 660 inst->alg.base.cra_blocksize = 1; 661 inst->alg.base.cra_alignmask = chacha->base.cra_alignmask | 662 poly->cra_alignmask; 663 inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) + 664 ctx->saltlen; 665 inst->alg.ivsize = ivsize; 666 inst->alg.chunksize = crypto_skcipher_alg_chunksize(chacha); 667 inst->alg.maxauthsize = POLY1305_DIGEST_SIZE; 668 inst->alg.init = chachapoly_init; 669 inst->alg.exit = chachapoly_exit; 670 inst->alg.encrypt = chachapoly_encrypt; 671 inst->alg.decrypt = chachapoly_decrypt; 672 inst->alg.setkey = chachapoly_setkey; 673 inst->alg.setauthsize = chachapoly_setauthsize; 674 675 inst->free = chachapoly_free; 676 677 err = aead_register_instance(tmpl, inst); 678 if (err) 679 goto out_drop_chacha; 680 681 out_put_poly: 682 crypto_mod_put(poly); 683 return err; 684 685 out_drop_chacha: 686 crypto_drop_skcipher(&ctx->chacha); 687 err_drop_poly: 688 crypto_drop_ahash(&ctx->poly); 689 err_free_inst: 690 kfree(inst); 691 goto out_put_poly; 692 } 693 694 static int rfc7539_create(struct crypto_template *tmpl, struct rtattr **tb) 695 { 696 return chachapoly_create(tmpl, tb, "rfc7539", 12); 697 } 698 699 static int rfc7539esp_create(struct crypto_template *tmpl, struct rtattr **tb) 700 { 701 return chachapoly_create(tmpl, tb, "rfc7539esp", 8); 702 } 703 704 static struct crypto_template rfc7539_tmpls[] = { 705 { 706 .name = "rfc7539", 707 .create = rfc7539_create, 708 .module = THIS_MODULE, 709 }, { 710 .name = "rfc7539esp", 711 .create = rfc7539esp_create, 712 .module = THIS_MODULE, 713 }, 714 }; 715 716 static int __init chacha20poly1305_module_init(void) 717 { 718 return crypto_register_templates(rfc7539_tmpls, 719 ARRAY_SIZE(rfc7539_tmpls)); 720 } 721 722 static void __exit chacha20poly1305_module_exit(void) 723 { 724 crypto_unregister_templates(rfc7539_tmpls, 725 ARRAY_SIZE(rfc7539_tmpls)); 726 } 727 728 subsys_initcall(chacha20poly1305_module_init); 729 module_exit(chacha20poly1305_module_exit); 730 731 MODULE_LICENSE("GPL"); 732 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>"); 733 MODULE_DESCRIPTION("ChaCha20-Poly1305 AEAD"); 734 MODULE_ALIAS_CRYPTO("rfc7539"); 735 MODULE_ALIAS_CRYPTO("rfc7539esp"); 736