162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Adiantum length-preserving encryption mode
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2018 Google LLC
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/*
962306a36Sopenharmony_ci * Adiantum is a tweakable, length-preserving encryption mode designed for fast
1062306a36Sopenharmony_ci * and secure disk encryption, especially on CPUs without dedicated crypto
1162306a36Sopenharmony_ci * instructions.  Adiantum encrypts each sector using the XChaCha12 stream
1262306a36Sopenharmony_ci * cipher, two passes of an ε-almost-∆-universal (ε-∆U) hash function based on
1362306a36Sopenharmony_ci * NH and Poly1305, and an invocation of the AES-256 block cipher on a single
1462306a36Sopenharmony_ci * 16-byte block.  See the paper for details:
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *	Adiantum: length-preserving encryption for entry-level processors
1762306a36Sopenharmony_ci *      (https://eprint.iacr.org/2018/720.pdf)
1862306a36Sopenharmony_ci *
1962306a36Sopenharmony_ci * For flexibility, this implementation also allows other ciphers:
2062306a36Sopenharmony_ci *
2162306a36Sopenharmony_ci *	- Stream cipher: XChaCha12 or XChaCha20
2262306a36Sopenharmony_ci *	- Block cipher: any with a 128-bit block size and 256-bit key
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * This implementation doesn't currently allow other ε-∆U hash functions, i.e.
2562306a36Sopenharmony_ci * HPolyC is not supported.  This is because Adiantum is ~20% faster than HPolyC
2662306a36Sopenharmony_ci * but still provably as secure, and also the ε-∆U hash function of HBSH is
2762306a36Sopenharmony_ci * formally defined to take two inputs (tweak, message) which makes it difficult
2862306a36Sopenharmony_ci * to wrap with the crypto_shash API.  Rather, some details need to be handled
2962306a36Sopenharmony_ci * here.  Nevertheless, if needed in the future, support for other ε-∆U hash
3062306a36Sopenharmony_ci * functions could be added here.
3162306a36Sopenharmony_ci */
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#include <crypto/b128ops.h>
3462306a36Sopenharmony_ci#include <crypto/chacha.h>
3562306a36Sopenharmony_ci#include <crypto/internal/cipher.h>
3662306a36Sopenharmony_ci#include <crypto/internal/hash.h>
3762306a36Sopenharmony_ci#include <crypto/internal/poly1305.h>
3862306a36Sopenharmony_ci#include <crypto/internal/skcipher.h>
3962306a36Sopenharmony_ci#include <crypto/nhpoly1305.h>
4062306a36Sopenharmony_ci#include <crypto/scatterwalk.h>
4162306a36Sopenharmony_ci#include <linux/module.h>
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/*
4462306a36Sopenharmony_ci * Size of right-hand part of input data, in bytes; also the size of the block
4562306a36Sopenharmony_ci * cipher's block size and the hash function's output.
4662306a36Sopenharmony_ci */
4762306a36Sopenharmony_ci#define BLOCKCIPHER_BLOCK_SIZE		16
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* Size of the block cipher key (K_E) in bytes */
5062306a36Sopenharmony_ci#define BLOCKCIPHER_KEY_SIZE		32
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/* Size of the hash key (K_H) in bytes */
5362306a36Sopenharmony_ci#define HASH_KEY_SIZE		(POLY1305_BLOCK_SIZE + NHPOLY1305_KEY_SIZE)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/*
5662306a36Sopenharmony_ci * The specification allows variable-length tweaks, but Linux's crypto API
5762306a36Sopenharmony_ci * currently only allows algorithms to support a single length.  The "natural"
5862306a36Sopenharmony_ci * tweak length for Adiantum is 16, since that fits into one Poly1305 block for
5962306a36Sopenharmony_ci * the best performance.  But longer tweaks are useful for fscrypt, to avoid
6062306a36Sopenharmony_ci * needing to derive per-file keys.  So instead we use two blocks, or 32 bytes.
6162306a36Sopenharmony_ci */
6262306a36Sopenharmony_ci#define TWEAK_SIZE		32
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistruct adiantum_instance_ctx {
6562306a36Sopenharmony_ci	struct crypto_skcipher_spawn streamcipher_spawn;
6662306a36Sopenharmony_ci	struct crypto_cipher_spawn blockcipher_spawn;
6762306a36Sopenharmony_ci	struct crypto_shash_spawn hash_spawn;
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistruct adiantum_tfm_ctx {
7162306a36Sopenharmony_ci	struct crypto_skcipher *streamcipher;
7262306a36Sopenharmony_ci	struct crypto_cipher *blockcipher;
7362306a36Sopenharmony_ci	struct crypto_shash *hash;
7462306a36Sopenharmony_ci	struct poly1305_core_key header_hash_key;
7562306a36Sopenharmony_ci};
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistruct adiantum_request_ctx {
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	/*
8062306a36Sopenharmony_ci	 * Buffer for right-hand part of data, i.e.
8162306a36Sopenharmony_ci	 *
8262306a36Sopenharmony_ci	 *    P_L => P_M => C_M => C_R when encrypting, or
8362306a36Sopenharmony_ci	 *    C_R => C_M => P_M => P_L when decrypting.
8462306a36Sopenharmony_ci	 *
8562306a36Sopenharmony_ci	 * Also used to build the IV for the stream cipher.
8662306a36Sopenharmony_ci	 */
8762306a36Sopenharmony_ci	union {
8862306a36Sopenharmony_ci		u8 bytes[XCHACHA_IV_SIZE];
8962306a36Sopenharmony_ci		__le32 words[XCHACHA_IV_SIZE / sizeof(__le32)];
9062306a36Sopenharmony_ci		le128 bignum;	/* interpret as element of Z/(2^{128}Z) */
9162306a36Sopenharmony_ci	} rbuf;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	bool enc; /* true if encrypting, false if decrypting */
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	/*
9662306a36Sopenharmony_ci	 * The result of the Poly1305 ε-∆U hash function applied to
9762306a36Sopenharmony_ci	 * (bulk length, tweak)
9862306a36Sopenharmony_ci	 */
9962306a36Sopenharmony_ci	le128 header_hash;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	/* Sub-requests, must be last */
10262306a36Sopenharmony_ci	union {
10362306a36Sopenharmony_ci		struct shash_desc hash_desc;
10462306a36Sopenharmony_ci		struct skcipher_request streamcipher_req;
10562306a36Sopenharmony_ci	} u;
10662306a36Sopenharmony_ci};
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/*
10962306a36Sopenharmony_ci * Given the XChaCha stream key K_S, derive the block cipher key K_E and the
11062306a36Sopenharmony_ci * hash key K_H as follows:
11162306a36Sopenharmony_ci *
11262306a36Sopenharmony_ci *     K_E || K_H || ... = XChaCha(key=K_S, nonce=1||0^191)
11362306a36Sopenharmony_ci *
11462306a36Sopenharmony_ci * Note that this denotes using bits from the XChaCha keystream, which here we
11562306a36Sopenharmony_ci * get indirectly by encrypting a buffer containing all 0's.
11662306a36Sopenharmony_ci */
11762306a36Sopenharmony_cistatic int adiantum_setkey(struct crypto_skcipher *tfm, const u8 *key,
11862306a36Sopenharmony_ci			   unsigned int keylen)
11962306a36Sopenharmony_ci{
12062306a36Sopenharmony_ci	struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
12162306a36Sopenharmony_ci	struct {
12262306a36Sopenharmony_ci		u8 iv[XCHACHA_IV_SIZE];
12362306a36Sopenharmony_ci		u8 derived_keys[BLOCKCIPHER_KEY_SIZE + HASH_KEY_SIZE];
12462306a36Sopenharmony_ci		struct scatterlist sg;
12562306a36Sopenharmony_ci		struct crypto_wait wait;
12662306a36Sopenharmony_ci		struct skcipher_request req; /* must be last */
12762306a36Sopenharmony_ci	} *data;
12862306a36Sopenharmony_ci	u8 *keyp;
12962306a36Sopenharmony_ci	int err;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	/* Set the stream cipher key (K_S) */
13262306a36Sopenharmony_ci	crypto_skcipher_clear_flags(tctx->streamcipher, CRYPTO_TFM_REQ_MASK);
13362306a36Sopenharmony_ci	crypto_skcipher_set_flags(tctx->streamcipher,
13462306a36Sopenharmony_ci				  crypto_skcipher_get_flags(tfm) &
13562306a36Sopenharmony_ci				  CRYPTO_TFM_REQ_MASK);
13662306a36Sopenharmony_ci	err = crypto_skcipher_setkey(tctx->streamcipher, key, keylen);
13762306a36Sopenharmony_ci	if (err)
13862306a36Sopenharmony_ci		return err;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	/* Derive the subkeys */
14162306a36Sopenharmony_ci	data = kzalloc(sizeof(*data) +
14262306a36Sopenharmony_ci		       crypto_skcipher_reqsize(tctx->streamcipher), GFP_KERNEL);
14362306a36Sopenharmony_ci	if (!data)
14462306a36Sopenharmony_ci		return -ENOMEM;
14562306a36Sopenharmony_ci	data->iv[0] = 1;
14662306a36Sopenharmony_ci	sg_init_one(&data->sg, data->derived_keys, sizeof(data->derived_keys));
14762306a36Sopenharmony_ci	crypto_init_wait(&data->wait);
14862306a36Sopenharmony_ci	skcipher_request_set_tfm(&data->req, tctx->streamcipher);
14962306a36Sopenharmony_ci	skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
15062306a36Sopenharmony_ci						  CRYPTO_TFM_REQ_MAY_BACKLOG,
15162306a36Sopenharmony_ci				      crypto_req_done, &data->wait);
15262306a36Sopenharmony_ci	skcipher_request_set_crypt(&data->req, &data->sg, &data->sg,
15362306a36Sopenharmony_ci				   sizeof(data->derived_keys), data->iv);
15462306a36Sopenharmony_ci	err = crypto_wait_req(crypto_skcipher_encrypt(&data->req), &data->wait);
15562306a36Sopenharmony_ci	if (err)
15662306a36Sopenharmony_ci		goto out;
15762306a36Sopenharmony_ci	keyp = data->derived_keys;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	/* Set the block cipher key (K_E) */
16062306a36Sopenharmony_ci	crypto_cipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
16162306a36Sopenharmony_ci	crypto_cipher_set_flags(tctx->blockcipher,
16262306a36Sopenharmony_ci				crypto_skcipher_get_flags(tfm) &
16362306a36Sopenharmony_ci				CRYPTO_TFM_REQ_MASK);
16462306a36Sopenharmony_ci	err = crypto_cipher_setkey(tctx->blockcipher, keyp,
16562306a36Sopenharmony_ci				   BLOCKCIPHER_KEY_SIZE);
16662306a36Sopenharmony_ci	if (err)
16762306a36Sopenharmony_ci		goto out;
16862306a36Sopenharmony_ci	keyp += BLOCKCIPHER_KEY_SIZE;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	/* Set the hash key (K_H) */
17162306a36Sopenharmony_ci	poly1305_core_setkey(&tctx->header_hash_key, keyp);
17262306a36Sopenharmony_ci	keyp += POLY1305_BLOCK_SIZE;
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	crypto_shash_clear_flags(tctx->hash, CRYPTO_TFM_REQ_MASK);
17562306a36Sopenharmony_ci	crypto_shash_set_flags(tctx->hash, crypto_skcipher_get_flags(tfm) &
17662306a36Sopenharmony_ci					   CRYPTO_TFM_REQ_MASK);
17762306a36Sopenharmony_ci	err = crypto_shash_setkey(tctx->hash, keyp, NHPOLY1305_KEY_SIZE);
17862306a36Sopenharmony_ci	keyp += NHPOLY1305_KEY_SIZE;
17962306a36Sopenharmony_ci	WARN_ON(keyp != &data->derived_keys[ARRAY_SIZE(data->derived_keys)]);
18062306a36Sopenharmony_ciout:
18162306a36Sopenharmony_ci	kfree_sensitive(data);
18262306a36Sopenharmony_ci	return err;
18362306a36Sopenharmony_ci}
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci/* Addition in Z/(2^{128}Z) */
18662306a36Sopenharmony_cistatic inline void le128_add(le128 *r, const le128 *v1, const le128 *v2)
18762306a36Sopenharmony_ci{
18862306a36Sopenharmony_ci	u64 x = le64_to_cpu(v1->b);
18962306a36Sopenharmony_ci	u64 y = le64_to_cpu(v2->b);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	r->b = cpu_to_le64(x + y);
19262306a36Sopenharmony_ci	r->a = cpu_to_le64(le64_to_cpu(v1->a) + le64_to_cpu(v2->a) +
19362306a36Sopenharmony_ci			   (x + y < x));
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci/* Subtraction in Z/(2^{128}Z) */
19762306a36Sopenharmony_cistatic inline void le128_sub(le128 *r, const le128 *v1, const le128 *v2)
19862306a36Sopenharmony_ci{
19962306a36Sopenharmony_ci	u64 x = le64_to_cpu(v1->b);
20062306a36Sopenharmony_ci	u64 y = le64_to_cpu(v2->b);
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	r->b = cpu_to_le64(x - y);
20362306a36Sopenharmony_ci	r->a = cpu_to_le64(le64_to_cpu(v1->a) - le64_to_cpu(v2->a) -
20462306a36Sopenharmony_ci			   (x - y > x));
20562306a36Sopenharmony_ci}
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci/*
20862306a36Sopenharmony_ci * Apply the Poly1305 ε-∆U hash function to (bulk length, tweak) and save the
20962306a36Sopenharmony_ci * result to rctx->header_hash.  This is the calculation
21062306a36Sopenharmony_ci *
21162306a36Sopenharmony_ci *	H_T ← Poly1305_{K_T}(bin_{128}(|L|) || T)
21262306a36Sopenharmony_ci *
21362306a36Sopenharmony_ci * from the procedure in section 6.4 of the Adiantum paper.  The resulting value
21462306a36Sopenharmony_ci * is reused in both the first and second hash steps.  Specifically, it's added
21562306a36Sopenharmony_ci * to the result of an independently keyed ε-∆U hash function (for equal length
21662306a36Sopenharmony_ci * inputs only) taken over the left-hand part (the "bulk") of the message, to
21762306a36Sopenharmony_ci * give the overall Adiantum hash of the (tweak, left-hand part) pair.
21862306a36Sopenharmony_ci */
21962306a36Sopenharmony_cistatic void adiantum_hash_header(struct skcipher_request *req)
22062306a36Sopenharmony_ci{
22162306a36Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
22262306a36Sopenharmony_ci	const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
22362306a36Sopenharmony_ci	struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
22462306a36Sopenharmony_ci	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
22562306a36Sopenharmony_ci	struct {
22662306a36Sopenharmony_ci		__le64 message_bits;
22762306a36Sopenharmony_ci		__le64 padding;
22862306a36Sopenharmony_ci	} header = {
22962306a36Sopenharmony_ci		.message_bits = cpu_to_le64((u64)bulk_len * 8)
23062306a36Sopenharmony_ci	};
23162306a36Sopenharmony_ci	struct poly1305_state state;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	poly1305_core_init(&state);
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	BUILD_BUG_ON(sizeof(header) % POLY1305_BLOCK_SIZE != 0);
23662306a36Sopenharmony_ci	poly1305_core_blocks(&state, &tctx->header_hash_key,
23762306a36Sopenharmony_ci			     &header, sizeof(header) / POLY1305_BLOCK_SIZE, 1);
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	BUILD_BUG_ON(TWEAK_SIZE % POLY1305_BLOCK_SIZE != 0);
24062306a36Sopenharmony_ci	poly1305_core_blocks(&state, &tctx->header_hash_key, req->iv,
24162306a36Sopenharmony_ci			     TWEAK_SIZE / POLY1305_BLOCK_SIZE, 1);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	poly1305_core_emit(&state, NULL, &rctx->header_hash);
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci/* Hash the left-hand part (the "bulk") of the message using NHPoly1305 */
24762306a36Sopenharmony_cistatic int adiantum_hash_message(struct skcipher_request *req,
24862306a36Sopenharmony_ci				 struct scatterlist *sgl, le128 *digest)
24962306a36Sopenharmony_ci{
25062306a36Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
25162306a36Sopenharmony_ci	const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
25262306a36Sopenharmony_ci	struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
25362306a36Sopenharmony_ci	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
25462306a36Sopenharmony_ci	struct shash_desc *hash_desc = &rctx->u.hash_desc;
25562306a36Sopenharmony_ci	struct sg_mapping_iter miter;
25662306a36Sopenharmony_ci	unsigned int i, n;
25762306a36Sopenharmony_ci	int err;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	hash_desc->tfm = tctx->hash;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	err = crypto_shash_init(hash_desc);
26262306a36Sopenharmony_ci	if (err)
26362306a36Sopenharmony_ci		return err;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	sg_miter_start(&miter, sgl, sg_nents(sgl),
26662306a36Sopenharmony_ci		       SG_MITER_FROM_SG | SG_MITER_ATOMIC);
26762306a36Sopenharmony_ci	for (i = 0; i < bulk_len; i += n) {
26862306a36Sopenharmony_ci		sg_miter_next(&miter);
26962306a36Sopenharmony_ci		n = min_t(unsigned int, miter.length, bulk_len - i);
27062306a36Sopenharmony_ci		err = crypto_shash_update(hash_desc, miter.addr, n);
27162306a36Sopenharmony_ci		if (err)
27262306a36Sopenharmony_ci			break;
27362306a36Sopenharmony_ci	}
27462306a36Sopenharmony_ci	sg_miter_stop(&miter);
27562306a36Sopenharmony_ci	if (err)
27662306a36Sopenharmony_ci		return err;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	return crypto_shash_final(hash_desc, (u8 *)digest);
27962306a36Sopenharmony_ci}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci/* Continue Adiantum encryption/decryption after the stream cipher step */
28262306a36Sopenharmony_cistatic int adiantum_finish(struct skcipher_request *req)
28362306a36Sopenharmony_ci{
28462306a36Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
28562306a36Sopenharmony_ci	const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
28662306a36Sopenharmony_ci	struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
28762306a36Sopenharmony_ci	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
28862306a36Sopenharmony_ci	le128 digest;
28962306a36Sopenharmony_ci	int err;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	/* If decrypting, decrypt C_M with the block cipher to get P_M */
29262306a36Sopenharmony_ci	if (!rctx->enc)
29362306a36Sopenharmony_ci		crypto_cipher_decrypt_one(tctx->blockcipher, rctx->rbuf.bytes,
29462306a36Sopenharmony_ci					  rctx->rbuf.bytes);
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	/*
29762306a36Sopenharmony_ci	 * Second hash step
29862306a36Sopenharmony_ci	 *	enc: C_R = C_M - H_{K_H}(T, C_L)
29962306a36Sopenharmony_ci	 *	dec: P_R = P_M - H_{K_H}(T, P_L)
30062306a36Sopenharmony_ci	 */
30162306a36Sopenharmony_ci	err = adiantum_hash_message(req, req->dst, &digest);
30262306a36Sopenharmony_ci	if (err)
30362306a36Sopenharmony_ci		return err;
30462306a36Sopenharmony_ci	le128_add(&digest, &digest, &rctx->header_hash);
30562306a36Sopenharmony_ci	le128_sub(&rctx->rbuf.bignum, &rctx->rbuf.bignum, &digest);
30662306a36Sopenharmony_ci	scatterwalk_map_and_copy(&rctx->rbuf.bignum, req->dst,
30762306a36Sopenharmony_ci				 bulk_len, BLOCKCIPHER_BLOCK_SIZE, 1);
30862306a36Sopenharmony_ci	return 0;
30962306a36Sopenharmony_ci}
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_cistatic void adiantum_streamcipher_done(void *data, int err)
31262306a36Sopenharmony_ci{
31362306a36Sopenharmony_ci	struct skcipher_request *req = data;
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	if (!err)
31662306a36Sopenharmony_ci		err = adiantum_finish(req);
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	skcipher_request_complete(req, err);
31962306a36Sopenharmony_ci}
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_cistatic int adiantum_crypt(struct skcipher_request *req, bool enc)
32262306a36Sopenharmony_ci{
32362306a36Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
32462306a36Sopenharmony_ci	const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
32562306a36Sopenharmony_ci	struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
32662306a36Sopenharmony_ci	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
32762306a36Sopenharmony_ci	unsigned int stream_len;
32862306a36Sopenharmony_ci	le128 digest;
32962306a36Sopenharmony_ci	int err;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	if (req->cryptlen < BLOCKCIPHER_BLOCK_SIZE)
33262306a36Sopenharmony_ci		return -EINVAL;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	rctx->enc = enc;
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	/*
33762306a36Sopenharmony_ci	 * First hash step
33862306a36Sopenharmony_ci	 *	enc: P_M = P_R + H_{K_H}(T, P_L)
33962306a36Sopenharmony_ci	 *	dec: C_M = C_R + H_{K_H}(T, C_L)
34062306a36Sopenharmony_ci	 */
34162306a36Sopenharmony_ci	adiantum_hash_header(req);
34262306a36Sopenharmony_ci	err = adiantum_hash_message(req, req->src, &digest);
34362306a36Sopenharmony_ci	if (err)
34462306a36Sopenharmony_ci		return err;
34562306a36Sopenharmony_ci	le128_add(&digest, &digest, &rctx->header_hash);
34662306a36Sopenharmony_ci	scatterwalk_map_and_copy(&rctx->rbuf.bignum, req->src,
34762306a36Sopenharmony_ci				 bulk_len, BLOCKCIPHER_BLOCK_SIZE, 0);
34862306a36Sopenharmony_ci	le128_add(&rctx->rbuf.bignum, &rctx->rbuf.bignum, &digest);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	/* If encrypting, encrypt P_M with the block cipher to get C_M */
35162306a36Sopenharmony_ci	if (enc)
35262306a36Sopenharmony_ci		crypto_cipher_encrypt_one(tctx->blockcipher, rctx->rbuf.bytes,
35362306a36Sopenharmony_ci					  rctx->rbuf.bytes);
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	/* Initialize the rest of the XChaCha IV (first part is C_M) */
35662306a36Sopenharmony_ci	BUILD_BUG_ON(BLOCKCIPHER_BLOCK_SIZE != 16);
35762306a36Sopenharmony_ci	BUILD_BUG_ON(XCHACHA_IV_SIZE != 32);	/* nonce || stream position */
35862306a36Sopenharmony_ci	rctx->rbuf.words[4] = cpu_to_le32(1);
35962306a36Sopenharmony_ci	rctx->rbuf.words[5] = 0;
36062306a36Sopenharmony_ci	rctx->rbuf.words[6] = 0;
36162306a36Sopenharmony_ci	rctx->rbuf.words[7] = 0;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	/*
36462306a36Sopenharmony_ci	 * XChaCha needs to be done on all the data except the last 16 bytes;
36562306a36Sopenharmony_ci	 * for disk encryption that usually means 4080 or 496 bytes.  But ChaCha
36662306a36Sopenharmony_ci	 * implementations tend to be most efficient when passed a whole number
36762306a36Sopenharmony_ci	 * of 64-byte ChaCha blocks, or sometimes even a multiple of 256 bytes.
36862306a36Sopenharmony_ci	 * And here it doesn't matter whether the last 16 bytes are written to,
36962306a36Sopenharmony_ci	 * as the second hash step will overwrite them.  Thus, round the XChaCha
37062306a36Sopenharmony_ci	 * length up to the next 64-byte boundary if possible.
37162306a36Sopenharmony_ci	 */
37262306a36Sopenharmony_ci	stream_len = bulk_len;
37362306a36Sopenharmony_ci	if (round_up(stream_len, CHACHA_BLOCK_SIZE) <= req->cryptlen)
37462306a36Sopenharmony_ci		stream_len = round_up(stream_len, CHACHA_BLOCK_SIZE);
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	skcipher_request_set_tfm(&rctx->u.streamcipher_req, tctx->streamcipher);
37762306a36Sopenharmony_ci	skcipher_request_set_crypt(&rctx->u.streamcipher_req, req->src,
37862306a36Sopenharmony_ci				   req->dst, stream_len, &rctx->rbuf);
37962306a36Sopenharmony_ci	skcipher_request_set_callback(&rctx->u.streamcipher_req,
38062306a36Sopenharmony_ci				      req->base.flags,
38162306a36Sopenharmony_ci				      adiantum_streamcipher_done, req);
38262306a36Sopenharmony_ci	return crypto_skcipher_encrypt(&rctx->u.streamcipher_req) ?:
38362306a36Sopenharmony_ci		adiantum_finish(req);
38462306a36Sopenharmony_ci}
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_cistatic int adiantum_encrypt(struct skcipher_request *req)
38762306a36Sopenharmony_ci{
38862306a36Sopenharmony_ci	return adiantum_crypt(req, true);
38962306a36Sopenharmony_ci}
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_cistatic int adiantum_decrypt(struct skcipher_request *req)
39262306a36Sopenharmony_ci{
39362306a36Sopenharmony_ci	return adiantum_crypt(req, false);
39462306a36Sopenharmony_ci}
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_cistatic int adiantum_init_tfm(struct crypto_skcipher *tfm)
39762306a36Sopenharmony_ci{
39862306a36Sopenharmony_ci	struct skcipher_instance *inst = skcipher_alg_instance(tfm);
39962306a36Sopenharmony_ci	struct adiantum_instance_ctx *ictx = skcipher_instance_ctx(inst);
40062306a36Sopenharmony_ci	struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
40162306a36Sopenharmony_ci	struct crypto_skcipher *streamcipher;
40262306a36Sopenharmony_ci	struct crypto_cipher *blockcipher;
40362306a36Sopenharmony_ci	struct crypto_shash *hash;
40462306a36Sopenharmony_ci	unsigned int subreq_size;
40562306a36Sopenharmony_ci	int err;
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	streamcipher = crypto_spawn_skcipher(&ictx->streamcipher_spawn);
40862306a36Sopenharmony_ci	if (IS_ERR(streamcipher))
40962306a36Sopenharmony_ci		return PTR_ERR(streamcipher);
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn);
41262306a36Sopenharmony_ci	if (IS_ERR(blockcipher)) {
41362306a36Sopenharmony_ci		err = PTR_ERR(blockcipher);
41462306a36Sopenharmony_ci		goto err_free_streamcipher;
41562306a36Sopenharmony_ci	}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	hash = crypto_spawn_shash(&ictx->hash_spawn);
41862306a36Sopenharmony_ci	if (IS_ERR(hash)) {
41962306a36Sopenharmony_ci		err = PTR_ERR(hash);
42062306a36Sopenharmony_ci		goto err_free_blockcipher;
42162306a36Sopenharmony_ci	}
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci	tctx->streamcipher = streamcipher;
42462306a36Sopenharmony_ci	tctx->blockcipher = blockcipher;
42562306a36Sopenharmony_ci	tctx->hash = hash;
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci	BUILD_BUG_ON(offsetofend(struct adiantum_request_ctx, u) !=
42862306a36Sopenharmony_ci		     sizeof(struct adiantum_request_ctx));
42962306a36Sopenharmony_ci	subreq_size = max(sizeof_field(struct adiantum_request_ctx,
43062306a36Sopenharmony_ci				       u.hash_desc) +
43162306a36Sopenharmony_ci			  crypto_shash_descsize(hash),
43262306a36Sopenharmony_ci			  sizeof_field(struct adiantum_request_ctx,
43362306a36Sopenharmony_ci				       u.streamcipher_req) +
43462306a36Sopenharmony_ci			  crypto_skcipher_reqsize(streamcipher));
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	crypto_skcipher_set_reqsize(tfm,
43762306a36Sopenharmony_ci				    offsetof(struct adiantum_request_ctx, u) +
43862306a36Sopenharmony_ci				    subreq_size);
43962306a36Sopenharmony_ci	return 0;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_cierr_free_blockcipher:
44262306a36Sopenharmony_ci	crypto_free_cipher(blockcipher);
44362306a36Sopenharmony_cierr_free_streamcipher:
44462306a36Sopenharmony_ci	crypto_free_skcipher(streamcipher);
44562306a36Sopenharmony_ci	return err;
44662306a36Sopenharmony_ci}
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_cistatic void adiantum_exit_tfm(struct crypto_skcipher *tfm)
44962306a36Sopenharmony_ci{
45062306a36Sopenharmony_ci	struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci	crypto_free_skcipher(tctx->streamcipher);
45362306a36Sopenharmony_ci	crypto_free_cipher(tctx->blockcipher);
45462306a36Sopenharmony_ci	crypto_free_shash(tctx->hash);
45562306a36Sopenharmony_ci}
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_cistatic void adiantum_free_instance(struct skcipher_instance *inst)
45862306a36Sopenharmony_ci{
45962306a36Sopenharmony_ci	struct adiantum_instance_ctx *ictx = skcipher_instance_ctx(inst);
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	crypto_drop_skcipher(&ictx->streamcipher_spawn);
46262306a36Sopenharmony_ci	crypto_drop_cipher(&ictx->blockcipher_spawn);
46362306a36Sopenharmony_ci	crypto_drop_shash(&ictx->hash_spawn);
46462306a36Sopenharmony_ci	kfree(inst);
46562306a36Sopenharmony_ci}
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci/*
46862306a36Sopenharmony_ci * Check for a supported set of inner algorithms.
46962306a36Sopenharmony_ci * See the comment at the beginning of this file.
47062306a36Sopenharmony_ci */
47162306a36Sopenharmony_cistatic bool adiantum_supported_algorithms(struct skcipher_alg *streamcipher_alg,
47262306a36Sopenharmony_ci					  struct crypto_alg *blockcipher_alg,
47362306a36Sopenharmony_ci					  struct shash_alg *hash_alg)
47462306a36Sopenharmony_ci{
47562306a36Sopenharmony_ci	if (strcmp(streamcipher_alg->base.cra_name, "xchacha12") != 0 &&
47662306a36Sopenharmony_ci	    strcmp(streamcipher_alg->base.cra_name, "xchacha20") != 0)
47762306a36Sopenharmony_ci		return false;
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	if (blockcipher_alg->cra_cipher.cia_min_keysize > BLOCKCIPHER_KEY_SIZE ||
48062306a36Sopenharmony_ci	    blockcipher_alg->cra_cipher.cia_max_keysize < BLOCKCIPHER_KEY_SIZE)
48162306a36Sopenharmony_ci		return false;
48262306a36Sopenharmony_ci	if (blockcipher_alg->cra_blocksize != BLOCKCIPHER_BLOCK_SIZE)
48362306a36Sopenharmony_ci		return false;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	if (strcmp(hash_alg->base.cra_name, "nhpoly1305") != 0)
48662306a36Sopenharmony_ci		return false;
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci	return true;
48962306a36Sopenharmony_ci}
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_cistatic int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
49262306a36Sopenharmony_ci{
49362306a36Sopenharmony_ci	u32 mask;
49462306a36Sopenharmony_ci	const char *nhpoly1305_name;
49562306a36Sopenharmony_ci	struct skcipher_instance *inst;
49662306a36Sopenharmony_ci	struct adiantum_instance_ctx *ictx;
49762306a36Sopenharmony_ci	struct skcipher_alg *streamcipher_alg;
49862306a36Sopenharmony_ci	struct crypto_alg *blockcipher_alg;
49962306a36Sopenharmony_ci	struct shash_alg *hash_alg;
50062306a36Sopenharmony_ci	int err;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
50362306a36Sopenharmony_ci	if (err)
50462306a36Sopenharmony_ci		return err;
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
50762306a36Sopenharmony_ci	if (!inst)
50862306a36Sopenharmony_ci		return -ENOMEM;
50962306a36Sopenharmony_ci	ictx = skcipher_instance_ctx(inst);
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	/* Stream cipher, e.g. "xchacha12" */
51262306a36Sopenharmony_ci	err = crypto_grab_skcipher(&ictx->streamcipher_spawn,
51362306a36Sopenharmony_ci				   skcipher_crypto_instance(inst),
51462306a36Sopenharmony_ci				   crypto_attr_alg_name(tb[1]), 0, mask);
51562306a36Sopenharmony_ci	if (err)
51662306a36Sopenharmony_ci		goto err_free_inst;
51762306a36Sopenharmony_ci	streamcipher_alg = crypto_spawn_skcipher_alg(&ictx->streamcipher_spawn);
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	/* Block cipher, e.g. "aes" */
52062306a36Sopenharmony_ci	err = crypto_grab_cipher(&ictx->blockcipher_spawn,
52162306a36Sopenharmony_ci				 skcipher_crypto_instance(inst),
52262306a36Sopenharmony_ci				 crypto_attr_alg_name(tb[2]), 0, mask);
52362306a36Sopenharmony_ci	if (err)
52462306a36Sopenharmony_ci		goto err_free_inst;
52562306a36Sopenharmony_ci	blockcipher_alg = crypto_spawn_cipher_alg(&ictx->blockcipher_spawn);
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci	/* NHPoly1305 ε-∆U hash function */
52862306a36Sopenharmony_ci	nhpoly1305_name = crypto_attr_alg_name(tb[3]);
52962306a36Sopenharmony_ci	if (nhpoly1305_name == ERR_PTR(-ENOENT))
53062306a36Sopenharmony_ci		nhpoly1305_name = "nhpoly1305";
53162306a36Sopenharmony_ci	err = crypto_grab_shash(&ictx->hash_spawn,
53262306a36Sopenharmony_ci				skcipher_crypto_instance(inst),
53362306a36Sopenharmony_ci				nhpoly1305_name, 0, mask);
53462306a36Sopenharmony_ci	if (err)
53562306a36Sopenharmony_ci		goto err_free_inst;
53662306a36Sopenharmony_ci	hash_alg = crypto_spawn_shash_alg(&ictx->hash_spawn);
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	/* Check the set of algorithms */
53962306a36Sopenharmony_ci	if (!adiantum_supported_algorithms(streamcipher_alg, blockcipher_alg,
54062306a36Sopenharmony_ci					   hash_alg)) {
54162306a36Sopenharmony_ci		pr_warn("Unsupported Adiantum instantiation: (%s,%s,%s)\n",
54262306a36Sopenharmony_ci			streamcipher_alg->base.cra_name,
54362306a36Sopenharmony_ci			blockcipher_alg->cra_name, hash_alg->base.cra_name);
54462306a36Sopenharmony_ci		err = -EINVAL;
54562306a36Sopenharmony_ci		goto err_free_inst;
54662306a36Sopenharmony_ci	}
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	/* Instance fields */
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	err = -ENAMETOOLONG;
55162306a36Sopenharmony_ci	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
55262306a36Sopenharmony_ci		     "adiantum(%s,%s)", streamcipher_alg->base.cra_name,
55362306a36Sopenharmony_ci		     blockcipher_alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
55462306a36Sopenharmony_ci		goto err_free_inst;
55562306a36Sopenharmony_ci	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
55662306a36Sopenharmony_ci		     "adiantum(%s,%s,%s)",
55762306a36Sopenharmony_ci		     streamcipher_alg->base.cra_driver_name,
55862306a36Sopenharmony_ci		     blockcipher_alg->cra_driver_name,
55962306a36Sopenharmony_ci		     hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
56062306a36Sopenharmony_ci		goto err_free_inst;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
56362306a36Sopenharmony_ci	inst->alg.base.cra_ctxsize = sizeof(struct adiantum_tfm_ctx);
56462306a36Sopenharmony_ci	inst->alg.base.cra_alignmask = streamcipher_alg->base.cra_alignmask |
56562306a36Sopenharmony_ci				       hash_alg->base.cra_alignmask;
56662306a36Sopenharmony_ci	/*
56762306a36Sopenharmony_ci	 * The block cipher is only invoked once per message, so for long
56862306a36Sopenharmony_ci	 * messages (e.g. sectors for disk encryption) its performance doesn't
56962306a36Sopenharmony_ci	 * matter as much as that of the stream cipher and hash function.  Thus,
57062306a36Sopenharmony_ci	 * weigh the block cipher's ->cra_priority less.
57162306a36Sopenharmony_ci	 */
57262306a36Sopenharmony_ci	inst->alg.base.cra_priority = (4 * streamcipher_alg->base.cra_priority +
57362306a36Sopenharmony_ci				       2 * hash_alg->base.cra_priority +
57462306a36Sopenharmony_ci				       blockcipher_alg->cra_priority) / 7;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	inst->alg.setkey = adiantum_setkey;
57762306a36Sopenharmony_ci	inst->alg.encrypt = adiantum_encrypt;
57862306a36Sopenharmony_ci	inst->alg.decrypt = adiantum_decrypt;
57962306a36Sopenharmony_ci	inst->alg.init = adiantum_init_tfm;
58062306a36Sopenharmony_ci	inst->alg.exit = adiantum_exit_tfm;
58162306a36Sopenharmony_ci	inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(streamcipher_alg);
58262306a36Sopenharmony_ci	inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(streamcipher_alg);
58362306a36Sopenharmony_ci	inst->alg.ivsize = TWEAK_SIZE;
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	inst->free = adiantum_free_instance;
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci	err = skcipher_register_instance(tmpl, inst);
58862306a36Sopenharmony_ci	if (err) {
58962306a36Sopenharmony_cierr_free_inst:
59062306a36Sopenharmony_ci		adiantum_free_instance(inst);
59162306a36Sopenharmony_ci	}
59262306a36Sopenharmony_ci	return err;
59362306a36Sopenharmony_ci}
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci/* adiantum(streamcipher_name, blockcipher_name [, nhpoly1305_name]) */
59662306a36Sopenharmony_cistatic struct crypto_template adiantum_tmpl = {
59762306a36Sopenharmony_ci	.name = "adiantum",
59862306a36Sopenharmony_ci	.create = adiantum_create,
59962306a36Sopenharmony_ci	.module = THIS_MODULE,
60062306a36Sopenharmony_ci};
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_cistatic int __init adiantum_module_init(void)
60362306a36Sopenharmony_ci{
60462306a36Sopenharmony_ci	return crypto_register_template(&adiantum_tmpl);
60562306a36Sopenharmony_ci}
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_cistatic void __exit adiantum_module_exit(void)
60862306a36Sopenharmony_ci{
60962306a36Sopenharmony_ci	crypto_unregister_template(&adiantum_tmpl);
61062306a36Sopenharmony_ci}
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_cisubsys_initcall(adiantum_module_init);
61362306a36Sopenharmony_cimodule_exit(adiantum_module_exit);
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ciMODULE_DESCRIPTION("Adiantum length-preserving encryption mode");
61662306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
61762306a36Sopenharmony_ciMODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
61862306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("adiantum");
61962306a36Sopenharmony_ciMODULE_IMPORT_NS(CRYPTO_INTERNAL);
620