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