linux/crypto/hctr2.c

// SPDX-License-Identifier: GPL-2.0
/*
 * HCTR2 length-preserving encryption mode
 *
 * Copyright 2021 Google LLC
 */


/*
 * HCTR2 is a length-preserving encryption mode that is efficient on
 * processors with instructions to accelerate AES and carryless
 * multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
 * processors with the ARMv8 crypto extensions.
 *
 * For more details, see the paper: "Length-preserving encryption with HCTR2"
 * (https://eprint.iacr.org/2021/1441.pdf)
 */

#include <crypto/internal/cipher.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <crypto/polyval.h>
#include <crypto/scatterwalk.h>
#include <linux/module.h>

#define BLOCKCIPHER_BLOCK_SIZE

/*
 * The specification allows variable-length tweaks, but Linux's crypto API
 * currently only allows algorithms to support a single length.  The "natural"
 * tweak length for HCTR2 is 16, since that fits into one POLYVAL block for
 * the best performance.  But longer tweaks are useful for fscrypt, to avoid
 * needing to derive per-file keys.  So instead we use two blocks, or 32 bytes.
 */
#define TWEAK_SIZE

struct hctr2_instance_ctx {};

struct hctr2_tfm_ctx {};

struct hctr2_request_ctx {};

static inline u8 *hctr2_hashed_tweaklen(const struct hctr2_tfm_ctx *tctx,
					bool has_remainder)
{}

static inline u8 *hctr2_hashed_tweak(const struct hctr2_tfm_ctx *tctx,
				     struct hctr2_request_ctx *rctx)
{}

/*
 * The input data for each HCTR2 hash step begins with a 16-byte block that
 * contains the tweak length and a flag that indicates whether the input is evenly
 * divisible into blocks.  Since this implementation only supports one tweak
 * length, we precompute the two hash states resulting from hashing the two
 * possible values of this initial block.  This reduces by one block the amount of
 * data that needs to be hashed for each encryption/decryption
 *
 * These precomputed hashes are stored in hctr2_tfm_ctx.
 */
static int hctr2_hash_tweaklen(struct hctr2_tfm_ctx *tctx, bool has_remainder)
{}

static int hctr2_setkey(struct crypto_skcipher *tfm, const u8 *key,
			unsigned int keylen)
{}

static int hctr2_hash_tweak(struct skcipher_request *req)
{}

static int hctr2_hash_message(struct skcipher_request *req,
			      struct scatterlist *sgl,
			      u8 digest[POLYVAL_DIGEST_SIZE])
{}

static int hctr2_finish(struct skcipher_request *req)
{}

static void hctr2_xctr_done(void *data, int err)
{}

static int hctr2_crypt(struct skcipher_request *req, bool enc)
{}

static int hctr2_encrypt(struct skcipher_request *req)
{}

static int hctr2_decrypt(struct skcipher_request *req)
{}

static int hctr2_init_tfm(struct crypto_skcipher *tfm)
{}

static void hctr2_exit_tfm(struct crypto_skcipher *tfm)
{}

static void hctr2_free_instance(struct skcipher_instance *inst)
{}

static int hctr2_create_common(struct crypto_template *tmpl,
			       struct rtattr **tb,
			       const char *xctr_name,
			       const char *polyval_name)
{}

static int hctr2_create_base(struct crypto_template *tmpl, struct rtattr **tb)
{}

static int hctr2_create(struct crypto_template *tmpl, struct rtattr **tb)
{}

static struct crypto_template hctr2_tmpls[] =;

static int __init hctr2_module_init(void)
{}

static void __exit hctr2_module_exit(void)
{}

subsys_initcall(hctr2_module_init);
module_exit(hctr2_module_exit);

MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_ALIAS_CRYPTO();
MODULE_IMPORT_NS();