18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Adiantum length-preserving encryption mode
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2018 Google LLC
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * Adiantum is a tweakable, length-preserving encryption mode designed for fast
108c2ecf20Sopenharmony_ci * and secure disk encryption, especially on CPUs without dedicated crypto
118c2ecf20Sopenharmony_ci * instructions.  Adiantum encrypts each sector using the XChaCha12 stream
128c2ecf20Sopenharmony_ci * cipher, two passes of an ε-almost-∆-universal (ε-∆U) hash function based on
138c2ecf20Sopenharmony_ci * NH and Poly1305, and an invocation of the AES-256 block cipher on a single
148c2ecf20Sopenharmony_ci * 16-byte block.  See the paper for details:
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *	Adiantum: length-preserving encryption for entry-level processors
178c2ecf20Sopenharmony_ci *      (https://eprint.iacr.org/2018/720.pdf)
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * For flexibility, this implementation also allows other ciphers:
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci *	- Stream cipher: XChaCha12 or XChaCha20
228c2ecf20Sopenharmony_ci *	- Block cipher: any with a 128-bit block size and 256-bit key
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * This implementation doesn't currently allow other ε-∆U hash functions, i.e.
258c2ecf20Sopenharmony_ci * HPolyC is not supported.  This is because Adiantum is ~20% faster than HPolyC
268c2ecf20Sopenharmony_ci * but still provably as secure, and also the ε-∆U hash function of HBSH is
278c2ecf20Sopenharmony_ci * formally defined to take two inputs (tweak, message) which makes it difficult
288c2ecf20Sopenharmony_ci * to wrap with the crypto_shash API.  Rather, some details need to be handled
298c2ecf20Sopenharmony_ci * here.  Nevertheless, if needed in the future, support for other ε-∆U hash
308c2ecf20Sopenharmony_ci * functions could be added here.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#include <crypto/b128ops.h>
348c2ecf20Sopenharmony_ci#include <crypto/chacha.h>
358c2ecf20Sopenharmony_ci#include <crypto/internal/hash.h>
368c2ecf20Sopenharmony_ci#include <crypto/internal/poly1305.h>
378c2ecf20Sopenharmony_ci#include <crypto/internal/skcipher.h>
388c2ecf20Sopenharmony_ci#include <crypto/nhpoly1305.h>
398c2ecf20Sopenharmony_ci#include <crypto/scatterwalk.h>
408c2ecf20Sopenharmony_ci#include <linux/module.h>
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/*
438c2ecf20Sopenharmony_ci * Size of right-hand part of input data, in bytes; also the size of the block
448c2ecf20Sopenharmony_ci * cipher's block size and the hash function's output.
458c2ecf20Sopenharmony_ci */
468c2ecf20Sopenharmony_ci#define BLOCKCIPHER_BLOCK_SIZE		16
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/* Size of the block cipher key (K_E) in bytes */
498c2ecf20Sopenharmony_ci#define BLOCKCIPHER_KEY_SIZE		32
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci/* Size of the hash key (K_H) in bytes */
528c2ecf20Sopenharmony_ci#define HASH_KEY_SIZE		(POLY1305_BLOCK_SIZE + NHPOLY1305_KEY_SIZE)
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/*
558c2ecf20Sopenharmony_ci * The specification allows variable-length tweaks, but Linux's crypto API
568c2ecf20Sopenharmony_ci * currently only allows algorithms to support a single length.  The "natural"
578c2ecf20Sopenharmony_ci * tweak length for Adiantum is 16, since that fits into one Poly1305 block for
588c2ecf20Sopenharmony_ci * the best performance.  But longer tweaks are useful for fscrypt, to avoid
598c2ecf20Sopenharmony_ci * needing to derive per-file keys.  So instead we use two blocks, or 32 bytes.
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_ci#define TWEAK_SIZE		32
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_cistruct adiantum_instance_ctx {
648c2ecf20Sopenharmony_ci	struct crypto_skcipher_spawn streamcipher_spawn;
658c2ecf20Sopenharmony_ci	struct crypto_cipher_spawn blockcipher_spawn;
668c2ecf20Sopenharmony_ci	struct crypto_shash_spawn hash_spawn;
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistruct adiantum_tfm_ctx {
708c2ecf20Sopenharmony_ci	struct crypto_skcipher *streamcipher;
718c2ecf20Sopenharmony_ci	struct crypto_cipher *blockcipher;
728c2ecf20Sopenharmony_ci	struct crypto_shash *hash;
738c2ecf20Sopenharmony_ci	struct poly1305_core_key header_hash_key;
748c2ecf20Sopenharmony_ci};
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistruct adiantum_request_ctx {
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	/*
798c2ecf20Sopenharmony_ci	 * Buffer for right-hand part of data, i.e.
808c2ecf20Sopenharmony_ci	 *
818c2ecf20Sopenharmony_ci	 *    P_L => P_M => C_M => C_R when encrypting, or
828c2ecf20Sopenharmony_ci	 *    C_R => C_M => P_M => P_L when decrypting.
838c2ecf20Sopenharmony_ci	 *
848c2ecf20Sopenharmony_ci	 * Also used to build the IV for the stream cipher.
858c2ecf20Sopenharmony_ci	 */
868c2ecf20Sopenharmony_ci	union {
878c2ecf20Sopenharmony_ci		u8 bytes[XCHACHA_IV_SIZE];
888c2ecf20Sopenharmony_ci		__le32 words[XCHACHA_IV_SIZE / sizeof(__le32)];
898c2ecf20Sopenharmony_ci		le128 bignum;	/* interpret as element of Z/(2^{128}Z) */
908c2ecf20Sopenharmony_ci	} rbuf;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	bool enc; /* true if encrypting, false if decrypting */
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/*
958c2ecf20Sopenharmony_ci	 * The result of the Poly1305 ε-∆U hash function applied to
968c2ecf20Sopenharmony_ci	 * (bulk length, tweak)
978c2ecf20Sopenharmony_ci	 */
988c2ecf20Sopenharmony_ci	le128 header_hash;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	/* Sub-requests, must be last */
1018c2ecf20Sopenharmony_ci	union {
1028c2ecf20Sopenharmony_ci		struct shash_desc hash_desc;
1038c2ecf20Sopenharmony_ci		struct skcipher_request streamcipher_req;
1048c2ecf20Sopenharmony_ci	} u;
1058c2ecf20Sopenharmony_ci};
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci/*
1088c2ecf20Sopenharmony_ci * Given the XChaCha stream key K_S, derive the block cipher key K_E and the
1098c2ecf20Sopenharmony_ci * hash key K_H as follows:
1108c2ecf20Sopenharmony_ci *
1118c2ecf20Sopenharmony_ci *     K_E || K_H || ... = XChaCha(key=K_S, nonce=1||0^191)
1128c2ecf20Sopenharmony_ci *
1138c2ecf20Sopenharmony_ci * Note that this denotes using bits from the XChaCha keystream, which here we
1148c2ecf20Sopenharmony_ci * get indirectly by encrypting a buffer containing all 0's.
1158c2ecf20Sopenharmony_ci */
1168c2ecf20Sopenharmony_cistatic int adiantum_setkey(struct crypto_skcipher *tfm, const u8 *key,
1178c2ecf20Sopenharmony_ci			   unsigned int keylen)
1188c2ecf20Sopenharmony_ci{
1198c2ecf20Sopenharmony_ci	struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
1208c2ecf20Sopenharmony_ci	struct {
1218c2ecf20Sopenharmony_ci		u8 iv[XCHACHA_IV_SIZE];
1228c2ecf20Sopenharmony_ci		u8 derived_keys[BLOCKCIPHER_KEY_SIZE + HASH_KEY_SIZE];
1238c2ecf20Sopenharmony_ci		struct scatterlist sg;
1248c2ecf20Sopenharmony_ci		struct crypto_wait wait;
1258c2ecf20Sopenharmony_ci		struct skcipher_request req; /* must be last */
1268c2ecf20Sopenharmony_ci	} *data;
1278c2ecf20Sopenharmony_ci	u8 *keyp;
1288c2ecf20Sopenharmony_ci	int err;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	/* Set the stream cipher key (K_S) */
1318c2ecf20Sopenharmony_ci	crypto_skcipher_clear_flags(tctx->streamcipher, CRYPTO_TFM_REQ_MASK);
1328c2ecf20Sopenharmony_ci	crypto_skcipher_set_flags(tctx->streamcipher,
1338c2ecf20Sopenharmony_ci				  crypto_skcipher_get_flags(tfm) &
1348c2ecf20Sopenharmony_ci				  CRYPTO_TFM_REQ_MASK);
1358c2ecf20Sopenharmony_ci	err = crypto_skcipher_setkey(tctx->streamcipher, key, keylen);
1368c2ecf20Sopenharmony_ci	if (err)
1378c2ecf20Sopenharmony_ci		return err;
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	/* Derive the subkeys */
1408c2ecf20Sopenharmony_ci	data = kzalloc(sizeof(*data) +
1418c2ecf20Sopenharmony_ci		       crypto_skcipher_reqsize(tctx->streamcipher), GFP_KERNEL);
1428c2ecf20Sopenharmony_ci	if (!data)
1438c2ecf20Sopenharmony_ci		return -ENOMEM;
1448c2ecf20Sopenharmony_ci	data->iv[0] = 1;
1458c2ecf20Sopenharmony_ci	sg_init_one(&data->sg, data->derived_keys, sizeof(data->derived_keys));
1468c2ecf20Sopenharmony_ci	crypto_init_wait(&data->wait);
1478c2ecf20Sopenharmony_ci	skcipher_request_set_tfm(&data->req, tctx->streamcipher);
1488c2ecf20Sopenharmony_ci	skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
1498c2ecf20Sopenharmony_ci						  CRYPTO_TFM_REQ_MAY_BACKLOG,
1508c2ecf20Sopenharmony_ci				      crypto_req_done, &data->wait);
1518c2ecf20Sopenharmony_ci	skcipher_request_set_crypt(&data->req, &data->sg, &data->sg,
1528c2ecf20Sopenharmony_ci				   sizeof(data->derived_keys), data->iv);
1538c2ecf20Sopenharmony_ci	err = crypto_wait_req(crypto_skcipher_encrypt(&data->req), &data->wait);
1548c2ecf20Sopenharmony_ci	if (err)
1558c2ecf20Sopenharmony_ci		goto out;
1568c2ecf20Sopenharmony_ci	keyp = data->derived_keys;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	/* Set the block cipher key (K_E) */
1598c2ecf20Sopenharmony_ci	crypto_cipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
1608c2ecf20Sopenharmony_ci	crypto_cipher_set_flags(tctx->blockcipher,
1618c2ecf20Sopenharmony_ci				crypto_skcipher_get_flags(tfm) &
1628c2ecf20Sopenharmony_ci				CRYPTO_TFM_REQ_MASK);
1638c2ecf20Sopenharmony_ci	err = crypto_cipher_setkey(tctx->blockcipher, keyp,
1648c2ecf20Sopenharmony_ci				   BLOCKCIPHER_KEY_SIZE);
1658c2ecf20Sopenharmony_ci	if (err)
1668c2ecf20Sopenharmony_ci		goto out;
1678c2ecf20Sopenharmony_ci	keyp += BLOCKCIPHER_KEY_SIZE;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	/* Set the hash key (K_H) */
1708c2ecf20Sopenharmony_ci	poly1305_core_setkey(&tctx->header_hash_key, keyp);
1718c2ecf20Sopenharmony_ci	keyp += POLY1305_BLOCK_SIZE;
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	crypto_shash_clear_flags(tctx->hash, CRYPTO_TFM_REQ_MASK);
1748c2ecf20Sopenharmony_ci	crypto_shash_set_flags(tctx->hash, crypto_skcipher_get_flags(tfm) &
1758c2ecf20Sopenharmony_ci					   CRYPTO_TFM_REQ_MASK);
1768c2ecf20Sopenharmony_ci	err = crypto_shash_setkey(tctx->hash, keyp, NHPOLY1305_KEY_SIZE);
1778c2ecf20Sopenharmony_ci	keyp += NHPOLY1305_KEY_SIZE;
1788c2ecf20Sopenharmony_ci	WARN_ON(keyp != &data->derived_keys[ARRAY_SIZE(data->derived_keys)]);
1798c2ecf20Sopenharmony_ciout:
1808c2ecf20Sopenharmony_ci	kfree_sensitive(data);
1818c2ecf20Sopenharmony_ci	return err;
1828c2ecf20Sopenharmony_ci}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci/* Addition in Z/(2^{128}Z) */
1858c2ecf20Sopenharmony_cistatic inline void le128_add(le128 *r, const le128 *v1, const le128 *v2)
1868c2ecf20Sopenharmony_ci{
1878c2ecf20Sopenharmony_ci	u64 x = le64_to_cpu(v1->b);
1888c2ecf20Sopenharmony_ci	u64 y = le64_to_cpu(v2->b);
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	r->b = cpu_to_le64(x + y);
1918c2ecf20Sopenharmony_ci	r->a = cpu_to_le64(le64_to_cpu(v1->a) + le64_to_cpu(v2->a) +
1928c2ecf20Sopenharmony_ci			   (x + y < x));
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci/* Subtraction in Z/(2^{128}Z) */
1968c2ecf20Sopenharmony_cistatic inline void le128_sub(le128 *r, const le128 *v1, const le128 *v2)
1978c2ecf20Sopenharmony_ci{
1988c2ecf20Sopenharmony_ci	u64 x = le64_to_cpu(v1->b);
1998c2ecf20Sopenharmony_ci	u64 y = le64_to_cpu(v2->b);
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci	r->b = cpu_to_le64(x - y);
2028c2ecf20Sopenharmony_ci	r->a = cpu_to_le64(le64_to_cpu(v1->a) - le64_to_cpu(v2->a) -
2038c2ecf20Sopenharmony_ci			   (x - y > x));
2048c2ecf20Sopenharmony_ci}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/*
2078c2ecf20Sopenharmony_ci * Apply the Poly1305 ε-∆U hash function to (bulk length, tweak) and save the
2088c2ecf20Sopenharmony_ci * result to rctx->header_hash.  This is the calculation
2098c2ecf20Sopenharmony_ci *
2108c2ecf20Sopenharmony_ci *	H_T ← Poly1305_{K_T}(bin_{128}(|L|) || T)
2118c2ecf20Sopenharmony_ci *
2128c2ecf20Sopenharmony_ci * from the procedure in section 6.4 of the Adiantum paper.  The resulting value
2138c2ecf20Sopenharmony_ci * is reused in both the first and second hash steps.  Specifically, it's added
2148c2ecf20Sopenharmony_ci * to the result of an independently keyed ε-∆U hash function (for equal length
2158c2ecf20Sopenharmony_ci * inputs only) taken over the left-hand part (the "bulk") of the message, to
2168c2ecf20Sopenharmony_ci * give the overall Adiantum hash of the (tweak, left-hand part) pair.
2178c2ecf20Sopenharmony_ci */
2188c2ecf20Sopenharmony_cistatic void adiantum_hash_header(struct skcipher_request *req)
2198c2ecf20Sopenharmony_ci{
2208c2ecf20Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
2218c2ecf20Sopenharmony_ci	const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
2228c2ecf20Sopenharmony_ci	struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
2238c2ecf20Sopenharmony_ci	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
2248c2ecf20Sopenharmony_ci	struct {
2258c2ecf20Sopenharmony_ci		__le64 message_bits;
2268c2ecf20Sopenharmony_ci		__le64 padding;
2278c2ecf20Sopenharmony_ci	} header = {
2288c2ecf20Sopenharmony_ci		.message_bits = cpu_to_le64((u64)bulk_len * 8)
2298c2ecf20Sopenharmony_ci	};
2308c2ecf20Sopenharmony_ci	struct poly1305_state state;
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	poly1305_core_init(&state);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	BUILD_BUG_ON(sizeof(header) % POLY1305_BLOCK_SIZE != 0);
2358c2ecf20Sopenharmony_ci	poly1305_core_blocks(&state, &tctx->header_hash_key,
2368c2ecf20Sopenharmony_ci			     &header, sizeof(header) / POLY1305_BLOCK_SIZE, 1);
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	BUILD_BUG_ON(TWEAK_SIZE % POLY1305_BLOCK_SIZE != 0);
2398c2ecf20Sopenharmony_ci	poly1305_core_blocks(&state, &tctx->header_hash_key, req->iv,
2408c2ecf20Sopenharmony_ci			     TWEAK_SIZE / POLY1305_BLOCK_SIZE, 1);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	poly1305_core_emit(&state, NULL, &rctx->header_hash);
2438c2ecf20Sopenharmony_ci}
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci/* Hash the left-hand part (the "bulk") of the message using NHPoly1305 */
2468c2ecf20Sopenharmony_cistatic int adiantum_hash_message(struct skcipher_request *req,
2478c2ecf20Sopenharmony_ci				 struct scatterlist *sgl, le128 *digest)
2488c2ecf20Sopenharmony_ci{
2498c2ecf20Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
2508c2ecf20Sopenharmony_ci	const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
2518c2ecf20Sopenharmony_ci	struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
2528c2ecf20Sopenharmony_ci	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
2538c2ecf20Sopenharmony_ci	struct shash_desc *hash_desc = &rctx->u.hash_desc;
2548c2ecf20Sopenharmony_ci	struct sg_mapping_iter miter;
2558c2ecf20Sopenharmony_ci	unsigned int i, n;
2568c2ecf20Sopenharmony_ci	int err;
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	hash_desc->tfm = tctx->hash;
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	err = crypto_shash_init(hash_desc);
2618c2ecf20Sopenharmony_ci	if (err)
2628c2ecf20Sopenharmony_ci		return err;
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	sg_miter_start(&miter, sgl, sg_nents(sgl),
2658c2ecf20Sopenharmony_ci		       SG_MITER_FROM_SG | SG_MITER_ATOMIC);
2668c2ecf20Sopenharmony_ci	for (i = 0; i < bulk_len; i += n) {
2678c2ecf20Sopenharmony_ci		sg_miter_next(&miter);
2688c2ecf20Sopenharmony_ci		n = min_t(unsigned int, miter.length, bulk_len - i);
2698c2ecf20Sopenharmony_ci		err = crypto_shash_update(hash_desc, miter.addr, n);
2708c2ecf20Sopenharmony_ci		if (err)
2718c2ecf20Sopenharmony_ci			break;
2728c2ecf20Sopenharmony_ci	}
2738c2ecf20Sopenharmony_ci	sg_miter_stop(&miter);
2748c2ecf20Sopenharmony_ci	if (err)
2758c2ecf20Sopenharmony_ci		return err;
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	return crypto_shash_final(hash_desc, (u8 *)digest);
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci/* Continue Adiantum encryption/decryption after the stream cipher step */
2818c2ecf20Sopenharmony_cistatic int adiantum_finish(struct skcipher_request *req)
2828c2ecf20Sopenharmony_ci{
2838c2ecf20Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
2848c2ecf20Sopenharmony_ci	const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
2858c2ecf20Sopenharmony_ci	struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
2868c2ecf20Sopenharmony_ci	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
2878c2ecf20Sopenharmony_ci	le128 digest;
2888c2ecf20Sopenharmony_ci	int err;
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	/* If decrypting, decrypt C_M with the block cipher to get P_M */
2918c2ecf20Sopenharmony_ci	if (!rctx->enc)
2928c2ecf20Sopenharmony_ci		crypto_cipher_decrypt_one(tctx->blockcipher, rctx->rbuf.bytes,
2938c2ecf20Sopenharmony_ci					  rctx->rbuf.bytes);
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	/*
2968c2ecf20Sopenharmony_ci	 * Second hash step
2978c2ecf20Sopenharmony_ci	 *	enc: C_R = C_M - H_{K_H}(T, C_L)
2988c2ecf20Sopenharmony_ci	 *	dec: P_R = P_M - H_{K_H}(T, P_L)
2998c2ecf20Sopenharmony_ci	 */
3008c2ecf20Sopenharmony_ci	err = adiantum_hash_message(req, req->dst, &digest);
3018c2ecf20Sopenharmony_ci	if (err)
3028c2ecf20Sopenharmony_ci		return err;
3038c2ecf20Sopenharmony_ci	le128_add(&digest, &digest, &rctx->header_hash);
3048c2ecf20Sopenharmony_ci	le128_sub(&rctx->rbuf.bignum, &rctx->rbuf.bignum, &digest);
3058c2ecf20Sopenharmony_ci	scatterwalk_map_and_copy(&rctx->rbuf.bignum, req->dst,
3068c2ecf20Sopenharmony_ci				 bulk_len, BLOCKCIPHER_BLOCK_SIZE, 1);
3078c2ecf20Sopenharmony_ci	return 0;
3088c2ecf20Sopenharmony_ci}
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_cistatic void adiantum_streamcipher_done(struct crypto_async_request *areq,
3118c2ecf20Sopenharmony_ci				       int err)
3128c2ecf20Sopenharmony_ci{
3138c2ecf20Sopenharmony_ci	struct skcipher_request *req = areq->data;
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	if (!err)
3168c2ecf20Sopenharmony_ci		err = adiantum_finish(req);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	skcipher_request_complete(req, err);
3198c2ecf20Sopenharmony_ci}
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_cistatic int adiantum_crypt(struct skcipher_request *req, bool enc)
3228c2ecf20Sopenharmony_ci{
3238c2ecf20Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
3248c2ecf20Sopenharmony_ci	const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
3258c2ecf20Sopenharmony_ci	struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
3268c2ecf20Sopenharmony_ci	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
3278c2ecf20Sopenharmony_ci	unsigned int stream_len;
3288c2ecf20Sopenharmony_ci	le128 digest;
3298c2ecf20Sopenharmony_ci	int err;
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	if (req->cryptlen < BLOCKCIPHER_BLOCK_SIZE)
3328c2ecf20Sopenharmony_ci		return -EINVAL;
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	rctx->enc = enc;
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	/*
3378c2ecf20Sopenharmony_ci	 * First hash step
3388c2ecf20Sopenharmony_ci	 *	enc: P_M = P_R + H_{K_H}(T, P_L)
3398c2ecf20Sopenharmony_ci	 *	dec: C_M = C_R + H_{K_H}(T, C_L)
3408c2ecf20Sopenharmony_ci	 */
3418c2ecf20Sopenharmony_ci	adiantum_hash_header(req);
3428c2ecf20Sopenharmony_ci	err = adiantum_hash_message(req, req->src, &digest);
3438c2ecf20Sopenharmony_ci	if (err)
3448c2ecf20Sopenharmony_ci		return err;
3458c2ecf20Sopenharmony_ci	le128_add(&digest, &digest, &rctx->header_hash);
3468c2ecf20Sopenharmony_ci	scatterwalk_map_and_copy(&rctx->rbuf.bignum, req->src,
3478c2ecf20Sopenharmony_ci				 bulk_len, BLOCKCIPHER_BLOCK_SIZE, 0);
3488c2ecf20Sopenharmony_ci	le128_add(&rctx->rbuf.bignum, &rctx->rbuf.bignum, &digest);
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci	/* If encrypting, encrypt P_M with the block cipher to get C_M */
3518c2ecf20Sopenharmony_ci	if (enc)
3528c2ecf20Sopenharmony_ci		crypto_cipher_encrypt_one(tctx->blockcipher, rctx->rbuf.bytes,
3538c2ecf20Sopenharmony_ci					  rctx->rbuf.bytes);
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	/* Initialize the rest of the XChaCha IV (first part is C_M) */
3568c2ecf20Sopenharmony_ci	BUILD_BUG_ON(BLOCKCIPHER_BLOCK_SIZE != 16);
3578c2ecf20Sopenharmony_ci	BUILD_BUG_ON(XCHACHA_IV_SIZE != 32);	/* nonce || stream position */
3588c2ecf20Sopenharmony_ci	rctx->rbuf.words[4] = cpu_to_le32(1);
3598c2ecf20Sopenharmony_ci	rctx->rbuf.words[5] = 0;
3608c2ecf20Sopenharmony_ci	rctx->rbuf.words[6] = 0;
3618c2ecf20Sopenharmony_ci	rctx->rbuf.words[7] = 0;
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci	/*
3648c2ecf20Sopenharmony_ci	 * XChaCha needs to be done on all the data except the last 16 bytes;
3658c2ecf20Sopenharmony_ci	 * for disk encryption that usually means 4080 or 496 bytes.  But ChaCha
3668c2ecf20Sopenharmony_ci	 * implementations tend to be most efficient when passed a whole number
3678c2ecf20Sopenharmony_ci	 * of 64-byte ChaCha blocks, or sometimes even a multiple of 256 bytes.
3688c2ecf20Sopenharmony_ci	 * And here it doesn't matter whether the last 16 bytes are written to,
3698c2ecf20Sopenharmony_ci	 * as the second hash step will overwrite them.  Thus, round the XChaCha
3708c2ecf20Sopenharmony_ci	 * length up to the next 64-byte boundary if possible.
3718c2ecf20Sopenharmony_ci	 */
3728c2ecf20Sopenharmony_ci	stream_len = bulk_len;
3738c2ecf20Sopenharmony_ci	if (round_up(stream_len, CHACHA_BLOCK_SIZE) <= req->cryptlen)
3748c2ecf20Sopenharmony_ci		stream_len = round_up(stream_len, CHACHA_BLOCK_SIZE);
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	skcipher_request_set_tfm(&rctx->u.streamcipher_req, tctx->streamcipher);
3778c2ecf20Sopenharmony_ci	skcipher_request_set_crypt(&rctx->u.streamcipher_req, req->src,
3788c2ecf20Sopenharmony_ci				   req->dst, stream_len, &rctx->rbuf);
3798c2ecf20Sopenharmony_ci	skcipher_request_set_callback(&rctx->u.streamcipher_req,
3808c2ecf20Sopenharmony_ci				      req->base.flags,
3818c2ecf20Sopenharmony_ci				      adiantum_streamcipher_done, req);
3828c2ecf20Sopenharmony_ci	return crypto_skcipher_encrypt(&rctx->u.streamcipher_req) ?:
3838c2ecf20Sopenharmony_ci		adiantum_finish(req);
3848c2ecf20Sopenharmony_ci}
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_cistatic int adiantum_encrypt(struct skcipher_request *req)
3878c2ecf20Sopenharmony_ci{
3888c2ecf20Sopenharmony_ci	return adiantum_crypt(req, true);
3898c2ecf20Sopenharmony_ci}
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_cistatic int adiantum_decrypt(struct skcipher_request *req)
3928c2ecf20Sopenharmony_ci{
3938c2ecf20Sopenharmony_ci	return adiantum_crypt(req, false);
3948c2ecf20Sopenharmony_ci}
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_cistatic int adiantum_init_tfm(struct crypto_skcipher *tfm)
3978c2ecf20Sopenharmony_ci{
3988c2ecf20Sopenharmony_ci	struct skcipher_instance *inst = skcipher_alg_instance(tfm);
3998c2ecf20Sopenharmony_ci	struct adiantum_instance_ctx *ictx = skcipher_instance_ctx(inst);
4008c2ecf20Sopenharmony_ci	struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
4018c2ecf20Sopenharmony_ci	struct crypto_skcipher *streamcipher;
4028c2ecf20Sopenharmony_ci	struct crypto_cipher *blockcipher;
4038c2ecf20Sopenharmony_ci	struct crypto_shash *hash;
4048c2ecf20Sopenharmony_ci	unsigned int subreq_size;
4058c2ecf20Sopenharmony_ci	int err;
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci	streamcipher = crypto_spawn_skcipher(&ictx->streamcipher_spawn);
4088c2ecf20Sopenharmony_ci	if (IS_ERR(streamcipher))
4098c2ecf20Sopenharmony_ci		return PTR_ERR(streamcipher);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn);
4128c2ecf20Sopenharmony_ci	if (IS_ERR(blockcipher)) {
4138c2ecf20Sopenharmony_ci		err = PTR_ERR(blockcipher);
4148c2ecf20Sopenharmony_ci		goto err_free_streamcipher;
4158c2ecf20Sopenharmony_ci	}
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ci	hash = crypto_spawn_shash(&ictx->hash_spawn);
4188c2ecf20Sopenharmony_ci	if (IS_ERR(hash)) {
4198c2ecf20Sopenharmony_ci		err = PTR_ERR(hash);
4208c2ecf20Sopenharmony_ci		goto err_free_blockcipher;
4218c2ecf20Sopenharmony_ci	}
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_ci	tctx->streamcipher = streamcipher;
4248c2ecf20Sopenharmony_ci	tctx->blockcipher = blockcipher;
4258c2ecf20Sopenharmony_ci	tctx->hash = hash;
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	BUILD_BUG_ON(offsetofend(struct adiantum_request_ctx, u) !=
4288c2ecf20Sopenharmony_ci		     sizeof(struct adiantum_request_ctx));
4298c2ecf20Sopenharmony_ci	subreq_size = max(sizeof_field(struct adiantum_request_ctx,
4308c2ecf20Sopenharmony_ci				       u.hash_desc) +
4318c2ecf20Sopenharmony_ci			  crypto_shash_descsize(hash),
4328c2ecf20Sopenharmony_ci			  sizeof_field(struct adiantum_request_ctx,
4338c2ecf20Sopenharmony_ci				       u.streamcipher_req) +
4348c2ecf20Sopenharmony_ci			  crypto_skcipher_reqsize(streamcipher));
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci	crypto_skcipher_set_reqsize(tfm,
4378c2ecf20Sopenharmony_ci				    offsetof(struct adiantum_request_ctx, u) +
4388c2ecf20Sopenharmony_ci				    subreq_size);
4398c2ecf20Sopenharmony_ci	return 0;
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_cierr_free_blockcipher:
4428c2ecf20Sopenharmony_ci	crypto_free_cipher(blockcipher);
4438c2ecf20Sopenharmony_cierr_free_streamcipher:
4448c2ecf20Sopenharmony_ci	crypto_free_skcipher(streamcipher);
4458c2ecf20Sopenharmony_ci	return err;
4468c2ecf20Sopenharmony_ci}
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_cistatic void adiantum_exit_tfm(struct crypto_skcipher *tfm)
4498c2ecf20Sopenharmony_ci{
4508c2ecf20Sopenharmony_ci	struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_ci	crypto_free_skcipher(tctx->streamcipher);
4538c2ecf20Sopenharmony_ci	crypto_free_cipher(tctx->blockcipher);
4548c2ecf20Sopenharmony_ci	crypto_free_shash(tctx->hash);
4558c2ecf20Sopenharmony_ci}
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_cistatic void adiantum_free_instance(struct skcipher_instance *inst)
4588c2ecf20Sopenharmony_ci{
4598c2ecf20Sopenharmony_ci	struct adiantum_instance_ctx *ictx = skcipher_instance_ctx(inst);
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci	crypto_drop_skcipher(&ictx->streamcipher_spawn);
4628c2ecf20Sopenharmony_ci	crypto_drop_cipher(&ictx->blockcipher_spawn);
4638c2ecf20Sopenharmony_ci	crypto_drop_shash(&ictx->hash_spawn);
4648c2ecf20Sopenharmony_ci	kfree(inst);
4658c2ecf20Sopenharmony_ci}
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci/*
4688c2ecf20Sopenharmony_ci * Check for a supported set of inner algorithms.
4698c2ecf20Sopenharmony_ci * See the comment at the beginning of this file.
4708c2ecf20Sopenharmony_ci */
4718c2ecf20Sopenharmony_cistatic bool adiantum_supported_algorithms(struct skcipher_alg *streamcipher_alg,
4728c2ecf20Sopenharmony_ci					  struct crypto_alg *blockcipher_alg,
4738c2ecf20Sopenharmony_ci					  struct shash_alg *hash_alg)
4748c2ecf20Sopenharmony_ci{
4758c2ecf20Sopenharmony_ci	if (strcmp(streamcipher_alg->base.cra_name, "xchacha12") != 0 &&
4768c2ecf20Sopenharmony_ci	    strcmp(streamcipher_alg->base.cra_name, "xchacha20") != 0)
4778c2ecf20Sopenharmony_ci		return false;
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	if (blockcipher_alg->cra_cipher.cia_min_keysize > BLOCKCIPHER_KEY_SIZE ||
4808c2ecf20Sopenharmony_ci	    blockcipher_alg->cra_cipher.cia_max_keysize < BLOCKCIPHER_KEY_SIZE)
4818c2ecf20Sopenharmony_ci		return false;
4828c2ecf20Sopenharmony_ci	if (blockcipher_alg->cra_blocksize != BLOCKCIPHER_BLOCK_SIZE)
4838c2ecf20Sopenharmony_ci		return false;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	if (strcmp(hash_alg->base.cra_name, "nhpoly1305") != 0)
4868c2ecf20Sopenharmony_ci		return false;
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	return true;
4898c2ecf20Sopenharmony_ci}
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_cistatic int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
4928c2ecf20Sopenharmony_ci{
4938c2ecf20Sopenharmony_ci	u32 mask;
4948c2ecf20Sopenharmony_ci	const char *nhpoly1305_name;
4958c2ecf20Sopenharmony_ci	struct skcipher_instance *inst;
4968c2ecf20Sopenharmony_ci	struct adiantum_instance_ctx *ictx;
4978c2ecf20Sopenharmony_ci	struct skcipher_alg *streamcipher_alg;
4988c2ecf20Sopenharmony_ci	struct crypto_alg *blockcipher_alg;
4998c2ecf20Sopenharmony_ci	struct shash_alg *hash_alg;
5008c2ecf20Sopenharmony_ci	int err;
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
5038c2ecf20Sopenharmony_ci	if (err)
5048c2ecf20Sopenharmony_ci		return err;
5058c2ecf20Sopenharmony_ci
5068c2ecf20Sopenharmony_ci	inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
5078c2ecf20Sopenharmony_ci	if (!inst)
5088c2ecf20Sopenharmony_ci		return -ENOMEM;
5098c2ecf20Sopenharmony_ci	ictx = skcipher_instance_ctx(inst);
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci	/* Stream cipher, e.g. "xchacha12" */
5128c2ecf20Sopenharmony_ci	err = crypto_grab_skcipher(&ictx->streamcipher_spawn,
5138c2ecf20Sopenharmony_ci				   skcipher_crypto_instance(inst),
5148c2ecf20Sopenharmony_ci				   crypto_attr_alg_name(tb[1]), 0, mask);
5158c2ecf20Sopenharmony_ci	if (err)
5168c2ecf20Sopenharmony_ci		goto err_free_inst;
5178c2ecf20Sopenharmony_ci	streamcipher_alg = crypto_spawn_skcipher_alg(&ictx->streamcipher_spawn);
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ci	/* Block cipher, e.g. "aes" */
5208c2ecf20Sopenharmony_ci	err = crypto_grab_cipher(&ictx->blockcipher_spawn,
5218c2ecf20Sopenharmony_ci				 skcipher_crypto_instance(inst),
5228c2ecf20Sopenharmony_ci				 crypto_attr_alg_name(tb[2]), 0, mask);
5238c2ecf20Sopenharmony_ci	if (err)
5248c2ecf20Sopenharmony_ci		goto err_free_inst;
5258c2ecf20Sopenharmony_ci	blockcipher_alg = crypto_spawn_cipher_alg(&ictx->blockcipher_spawn);
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_ci	/* NHPoly1305 ε-∆U hash function */
5288c2ecf20Sopenharmony_ci	nhpoly1305_name = crypto_attr_alg_name(tb[3]);
5298c2ecf20Sopenharmony_ci	if (nhpoly1305_name == ERR_PTR(-ENOENT))
5308c2ecf20Sopenharmony_ci		nhpoly1305_name = "nhpoly1305";
5318c2ecf20Sopenharmony_ci	err = crypto_grab_shash(&ictx->hash_spawn,
5328c2ecf20Sopenharmony_ci				skcipher_crypto_instance(inst),
5338c2ecf20Sopenharmony_ci				nhpoly1305_name, 0, mask);
5348c2ecf20Sopenharmony_ci	if (err)
5358c2ecf20Sopenharmony_ci		goto err_free_inst;
5368c2ecf20Sopenharmony_ci	hash_alg = crypto_spawn_shash_alg(&ictx->hash_spawn);
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	/* Check the set of algorithms */
5398c2ecf20Sopenharmony_ci	if (!adiantum_supported_algorithms(streamcipher_alg, blockcipher_alg,
5408c2ecf20Sopenharmony_ci					   hash_alg)) {
5418c2ecf20Sopenharmony_ci		pr_warn("Unsupported Adiantum instantiation: (%s,%s,%s)\n",
5428c2ecf20Sopenharmony_ci			streamcipher_alg->base.cra_name,
5438c2ecf20Sopenharmony_ci			blockcipher_alg->cra_name, hash_alg->base.cra_name);
5448c2ecf20Sopenharmony_ci		err = -EINVAL;
5458c2ecf20Sopenharmony_ci		goto err_free_inst;
5468c2ecf20Sopenharmony_ci	}
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci	/* Instance fields */
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci	err = -ENAMETOOLONG;
5518c2ecf20Sopenharmony_ci	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
5528c2ecf20Sopenharmony_ci		     "adiantum(%s,%s)", streamcipher_alg->base.cra_name,
5538c2ecf20Sopenharmony_ci		     blockcipher_alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
5548c2ecf20Sopenharmony_ci		goto err_free_inst;
5558c2ecf20Sopenharmony_ci	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
5568c2ecf20Sopenharmony_ci		     "adiantum(%s,%s,%s)",
5578c2ecf20Sopenharmony_ci		     streamcipher_alg->base.cra_driver_name,
5588c2ecf20Sopenharmony_ci		     blockcipher_alg->cra_driver_name,
5598c2ecf20Sopenharmony_ci		     hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
5608c2ecf20Sopenharmony_ci		goto err_free_inst;
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
5638c2ecf20Sopenharmony_ci	inst->alg.base.cra_ctxsize = sizeof(struct adiantum_tfm_ctx);
5648c2ecf20Sopenharmony_ci	inst->alg.base.cra_alignmask = streamcipher_alg->base.cra_alignmask |
5658c2ecf20Sopenharmony_ci				       hash_alg->base.cra_alignmask;
5668c2ecf20Sopenharmony_ci	/*
5678c2ecf20Sopenharmony_ci	 * The block cipher is only invoked once per message, so for long
5688c2ecf20Sopenharmony_ci	 * messages (e.g. sectors for disk encryption) its performance doesn't
5698c2ecf20Sopenharmony_ci	 * matter as much as that of the stream cipher and hash function.  Thus,
5708c2ecf20Sopenharmony_ci	 * weigh the block cipher's ->cra_priority less.
5718c2ecf20Sopenharmony_ci	 */
5728c2ecf20Sopenharmony_ci	inst->alg.base.cra_priority = (4 * streamcipher_alg->base.cra_priority +
5738c2ecf20Sopenharmony_ci				       2 * hash_alg->base.cra_priority +
5748c2ecf20Sopenharmony_ci				       blockcipher_alg->cra_priority) / 7;
5758c2ecf20Sopenharmony_ci
5768c2ecf20Sopenharmony_ci	inst->alg.setkey = adiantum_setkey;
5778c2ecf20Sopenharmony_ci	inst->alg.encrypt = adiantum_encrypt;
5788c2ecf20Sopenharmony_ci	inst->alg.decrypt = adiantum_decrypt;
5798c2ecf20Sopenharmony_ci	inst->alg.init = adiantum_init_tfm;
5808c2ecf20Sopenharmony_ci	inst->alg.exit = adiantum_exit_tfm;
5818c2ecf20Sopenharmony_ci	inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(streamcipher_alg);
5828c2ecf20Sopenharmony_ci	inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(streamcipher_alg);
5838c2ecf20Sopenharmony_ci	inst->alg.ivsize = TWEAK_SIZE;
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_ci	inst->free = adiantum_free_instance;
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci	err = skcipher_register_instance(tmpl, inst);
5888c2ecf20Sopenharmony_ci	if (err) {
5898c2ecf20Sopenharmony_cierr_free_inst:
5908c2ecf20Sopenharmony_ci		adiantum_free_instance(inst);
5918c2ecf20Sopenharmony_ci	}
5928c2ecf20Sopenharmony_ci	return err;
5938c2ecf20Sopenharmony_ci}
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci/* adiantum(streamcipher_name, blockcipher_name [, nhpoly1305_name]) */
5968c2ecf20Sopenharmony_cistatic struct crypto_template adiantum_tmpl = {
5978c2ecf20Sopenharmony_ci	.name = "adiantum",
5988c2ecf20Sopenharmony_ci	.create = adiantum_create,
5998c2ecf20Sopenharmony_ci	.module = THIS_MODULE,
6008c2ecf20Sopenharmony_ci};
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_cistatic int __init adiantum_module_init(void)
6038c2ecf20Sopenharmony_ci{
6048c2ecf20Sopenharmony_ci	return crypto_register_template(&adiantum_tmpl);
6058c2ecf20Sopenharmony_ci}
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_cistatic void __exit adiantum_module_exit(void)
6088c2ecf20Sopenharmony_ci{
6098c2ecf20Sopenharmony_ci	crypto_unregister_template(&adiantum_tmpl);
6108c2ecf20Sopenharmony_ci}
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_cisubsys_initcall(adiantum_module_init);
6138c2ecf20Sopenharmony_cimodule_exit(adiantum_module_exit);
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Adiantum length-preserving encryption mode");
6168c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
6178c2ecf20Sopenharmony_ciMODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
6188c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("adiantum");
619