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