#include <linux/completion.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/key.h>
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/blk-integrity.h>
#include <linux/mempool.h>
#include <linux/slab.h>
#include <linux/crypto.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#include <linux/backing-dev.h>
#include <linux/atomic.h>
#include <linux/scatterlist.h>
#include <linux/rbtree.h>
#include <linux/ctype.h>
#include <asm/page.h>
#include <asm/unaligned.h>
#include <crypto/hash.h>
#include <crypto/md5.h>
#include <crypto/skcipher.h>
#include <crypto/aead.h>
#include <crypto/authenc.h>
#include <crypto/utils.h>
#include <linux/rtnetlink.h>
#include <linux/key-type.h>
#include <keys/user-type.h>
#include <keys/encrypted-type.h>
#include <keys/trusted-type.h>
#include <linux/device-mapper.h>
#include "dm-audit.h"
#define DM_MSG_PREFIX …
static DEFINE_IDA(workqueue_ida);
struct convert_context { … };
struct dm_crypt_io { … } CRYPTO_MINALIGN_ATTR;
struct dm_crypt_request { … };
struct crypt_config;
struct crypt_iv_operations { … };
struct iv_benbi_private { … };
#define LMK_SEED_SIZE …
struct iv_lmk_private { … };
#define TCW_WHITENING_SIZE …
struct iv_tcw_private { … };
#define ELEPHANT_MAX_KEY_SIZE …
struct iv_elephant_private { … };
enum flags { … };
enum cipher_flags { … };
struct crypt_config { … };
#define MIN_IOS …
#define MAX_TAG_SIZE …
#define POOL_ENTRY_SIZE …
static DEFINE_SPINLOCK(dm_crypt_clients_lock);
static unsigned int dm_crypt_clients_n;
static volatile unsigned long dm_crypt_pages_per_client;
#define DM_CRYPT_MEMORY_PERCENT …
#define DM_CRYPT_MIN_PAGES_PER_CLIENT …
#define DM_CRYPT_DEFAULT_MAX_READ_SIZE …
#define DM_CRYPT_DEFAULT_MAX_WRITE_SIZE …
static unsigned int max_read_size = …;
module_param(max_read_size, uint, 0644);
MODULE_PARM_DESC(…) …;
static unsigned int max_write_size = …;
module_param(max_write_size, uint, 0644);
MODULE_PARM_DESC(…) …;
static unsigned get_max_request_size(struct crypt_config *cc, bool wrt)
{ … }
static void crypt_endio(struct bio *clone);
static void kcryptd_queue_crypt(struct dm_crypt_io *io);
static struct scatterlist *crypt_get_sg_data(struct crypt_config *cc,
struct scatterlist *sg);
static bool crypt_integrity_aead(struct crypt_config *cc);
static struct crypto_skcipher *any_tfm(struct crypt_config *cc)
{ … }
static struct crypto_aead *any_tfm_aead(struct crypt_config *cc)
{ … }
static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_plain64_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_plain64be_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti,
const char *opts)
{ … }
static void crypt_iv_benbi_dtr(struct crypt_config *cc)
{ … }
static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_null_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static void crypt_iv_lmk_dtr(struct crypt_config *cc)
{ … }
static int crypt_iv_lmk_ctr(struct crypt_config *cc, struct dm_target *ti,
const char *opts)
{ … }
static int crypt_iv_lmk_init(struct crypt_config *cc)
{ … }
static int crypt_iv_lmk_wipe(struct crypt_config *cc)
{ … }
static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq,
u8 *data)
{ … }
static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static void crypt_iv_tcw_dtr(struct crypt_config *cc)
{ … }
static int crypt_iv_tcw_ctr(struct crypt_config *cc, struct dm_target *ti,
const char *opts)
{ … }
static int crypt_iv_tcw_init(struct crypt_config *cc)
{ … }
static int crypt_iv_tcw_wipe(struct crypt_config *cc)
{ … }
static int crypt_iv_tcw_whitening(struct crypt_config *cc,
struct dm_crypt_request *dmreq,
u8 *data)
{ … }
static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_random_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_eboiv_ctr(struct crypt_config *cc, struct dm_target *ti,
const char *opts)
{ … }
static int crypt_iv_eboiv_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static void crypt_iv_elephant_dtr(struct crypt_config *cc)
{ … }
static int crypt_iv_elephant_ctr(struct crypt_config *cc, struct dm_target *ti,
const char *opts)
{ … }
static void diffuser_disk_to_cpu(u32 *d, size_t n)
{ … }
static void diffuser_cpu_to_disk(__le32 *d, size_t n)
{ … }
static void diffuser_a_decrypt(u32 *d, size_t n)
{ … }
static void diffuser_a_encrypt(u32 *d, size_t n)
{ … }
static void diffuser_b_decrypt(u32 *d, size_t n)
{ … }
static void diffuser_b_encrypt(u32 *d, size_t n)
{ … }
static int crypt_iv_elephant(struct crypt_config *cc, struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_elephant_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_elephant_post(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_iv_elephant_init(struct crypt_config *cc)
{ … }
static int crypt_iv_elephant_wipe(struct crypt_config *cc)
{ … }
static const struct crypt_iv_operations crypt_iv_plain_ops = …;
static const struct crypt_iv_operations crypt_iv_plain64_ops = …;
static const struct crypt_iv_operations crypt_iv_plain64be_ops = …;
static const struct crypt_iv_operations crypt_iv_essiv_ops = …;
static const struct crypt_iv_operations crypt_iv_benbi_ops = …;
static const struct crypt_iv_operations crypt_iv_null_ops = …;
static const struct crypt_iv_operations crypt_iv_lmk_ops = …;
static const struct crypt_iv_operations crypt_iv_tcw_ops = …;
static const struct crypt_iv_operations crypt_iv_random_ops = …;
static const struct crypt_iv_operations crypt_iv_eboiv_ops = …;
static const struct crypt_iv_operations crypt_iv_elephant_ops = …;
static bool crypt_integrity_aead(struct crypt_config *cc)
{ … }
static bool crypt_integrity_hmac(struct crypt_config *cc)
{ … }
static struct scatterlist *crypt_get_sg_data(struct crypt_config *cc,
struct scatterlist *sg)
{ … }
static int dm_crypt_integrity_io_alloc(struct dm_crypt_io *io, struct bio *bio)
{ … }
static int crypt_integrity_ctr(struct crypt_config *cc, struct dm_target *ti)
{ … }
static void crypt_convert_init(struct crypt_config *cc,
struct convert_context *ctx,
struct bio *bio_out, struct bio *bio_in,
sector_t sector)
{ … }
static struct dm_crypt_request *dmreq_of_req(struct crypt_config *cc,
void *req)
{ … }
static void *req_of_dmreq(struct crypt_config *cc, struct dm_crypt_request *dmreq)
{ … }
static u8 *iv_of_dmreq(struct crypt_config *cc,
struct dm_crypt_request *dmreq)
{ … }
static u8 *org_iv_of_dmreq(struct crypt_config *cc,
struct dm_crypt_request *dmreq)
{ … }
static __le64 *org_sector_of_dmreq(struct crypt_config *cc,
struct dm_crypt_request *dmreq)
{ … }
static unsigned int *org_tag_of_dmreq(struct crypt_config *cc,
struct dm_crypt_request *dmreq)
{ … }
static void *tag_from_dmreq(struct crypt_config *cc,
struct dm_crypt_request *dmreq)
{ … }
static void *iv_tag_from_dmreq(struct crypt_config *cc,
struct dm_crypt_request *dmreq)
{ … }
static int crypt_convert_block_aead(struct crypt_config *cc,
struct convert_context *ctx,
struct aead_request *req,
unsigned int tag_offset)
{ … }
static int crypt_convert_block_skcipher(struct crypt_config *cc,
struct convert_context *ctx,
struct skcipher_request *req,
unsigned int tag_offset)
{ … }
static void kcryptd_async_done(void *async_req, int error);
static int crypt_alloc_req_skcipher(struct crypt_config *cc,
struct convert_context *ctx)
{ … }
static int crypt_alloc_req_aead(struct crypt_config *cc,
struct convert_context *ctx)
{ … }
static int crypt_alloc_req(struct crypt_config *cc,
struct convert_context *ctx)
{ … }
static void crypt_free_req_skcipher(struct crypt_config *cc,
struct skcipher_request *req, struct bio *base_bio)
{ … }
static void crypt_free_req_aead(struct crypt_config *cc,
struct aead_request *req, struct bio *base_bio)
{ … }
static void crypt_free_req(struct crypt_config *cc, void *req, struct bio *base_bio)
{ … }
static blk_status_t crypt_convert(struct crypt_config *cc,
struct convert_context *ctx, bool atomic, bool reset_pending)
{ … }
static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone);
static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned int size)
{ … }
static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
{ … }
static void crypt_io_init(struct dm_crypt_io *io, struct crypt_config *cc,
struct bio *bio, sector_t sector)
{ … }
static void crypt_inc_pending(struct dm_crypt_io *io)
{ … }
static void kcryptd_queue_read(struct dm_crypt_io *io);
static void crypt_dec_pending(struct dm_crypt_io *io)
{ … }
static void crypt_endio(struct bio *clone)
{ … }
#define CRYPT_MAP_READ_GFP …
static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp)
{ … }
static void kcryptd_io_read_work(struct work_struct *work)
{ … }
static void kcryptd_queue_read(struct dm_crypt_io *io)
{ … }
static void kcryptd_io_write(struct dm_crypt_io *io)
{ … }
#define crypt_io_from_node(node) …
static int dmcrypt_write(void *data)
{ … }
static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async)
{ … }
static bool kcryptd_crypt_write_inline(struct crypt_config *cc,
struct convert_context *ctx)
{ … }
static void kcryptd_crypt_write_continue(struct work_struct *work)
{ … }
static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
{ … }
static void kcryptd_crypt_read_done(struct dm_crypt_io *io)
{ … }
static void kcryptd_crypt_read_continue(struct work_struct *work)
{ … }
static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
{ … }
static void kcryptd_async_done(void *data, int error)
{ … }
static void kcryptd_crypt(struct work_struct *work)
{ … }
static void kcryptd_queue_crypt(struct dm_crypt_io *io)
{ … }
static void crypt_free_tfms_aead(struct crypt_config *cc)
{ … }
static void crypt_free_tfms_skcipher(struct crypt_config *cc)
{ … }
static void crypt_free_tfms(struct crypt_config *cc)
{ … }
static int crypt_alloc_tfms_skcipher(struct crypt_config *cc, char *ciphermode)
{ … }
static int crypt_alloc_tfms_aead(struct crypt_config *cc, char *ciphermode)
{ … }
static int crypt_alloc_tfms(struct crypt_config *cc, char *ciphermode)
{ … }
static unsigned int crypt_subkey_size(struct crypt_config *cc)
{ … }
static unsigned int crypt_authenckey_size(struct crypt_config *cc)
{ … }
static void crypt_copy_authenckey(char *p, const void *key,
unsigned int enckeylen, unsigned int authkeylen)
{ … }
static int crypt_setkey(struct crypt_config *cc)
{ … }
#ifdef CONFIG_KEYS
static bool contains_whitespace(const char *str)
{ … }
static int set_key_user(struct crypt_config *cc, struct key *key)
{ … }
static int set_key_encrypted(struct crypt_config *cc, struct key *key)
{ … }
static int set_key_trusted(struct crypt_config *cc, struct key *key)
{ … }
static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string)
{ … }
static int get_key_size(char **key_string)
{ … }
#else
static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string)
{
return -EINVAL;
}
static int get_key_size(char **key_string)
{
return (*key_string[0] == ':') ? -EINVAL : (int)(strlen(*key_string) >> 1);
}
#endif
static int crypt_set_key(struct crypt_config *cc, char *key)
{ … }
static int crypt_wipe_key(struct crypt_config *cc)
{ … }
static void crypt_calculate_pages_per_client(void)
{ … }
static void *crypt_page_alloc(gfp_t gfp_mask, void *pool_data)
{ … }
static void crypt_page_free(void *page, void *pool_data)
{ … }
static void crypt_dtr(struct dm_target *ti)
{ … }
static int crypt_ctr_ivmode(struct dm_target *ti, const char *ivmode)
{ … }
static int crypt_ctr_auth_cipher(struct crypt_config *cc, char *cipher_api)
{ … }
static int crypt_ctr_cipher_new(struct dm_target *ti, char *cipher_in, char *key,
char **ivmode, char **ivopts)
{ … }
static int crypt_ctr_cipher_old(struct dm_target *ti, char *cipher_in, char *key,
char **ivmode, char **ivopts)
{ … }
static int crypt_ctr_cipher(struct dm_target *ti, char *cipher_in, char *key)
{ … }
static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **argv)
{ … }
#ifdef CONFIG_BLK_DEV_ZONED
static int crypt_report_zones(struct dm_target *ti,
struct dm_report_zones_args *args, unsigned int nr_zones)
{ … }
#else
#define crypt_report_zones …
#endif
static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{ … }
static int crypt_map(struct dm_target *ti, struct bio *bio)
{ … }
static char hex2asc(unsigned char c)
{ … }
static void crypt_status(struct dm_target *ti, status_type_t type,
unsigned int status_flags, char *result, unsigned int maxlen)
{ … }
static void crypt_postsuspend(struct dm_target *ti)
{ … }
static int crypt_preresume(struct dm_target *ti)
{ … }
static void crypt_resume(struct dm_target *ti)
{ … }
static int crypt_message(struct dm_target *ti, unsigned int argc, char **argv,
char *result, unsigned int maxlen)
{ … }
static int crypt_iterate_devices(struct dm_target *ti,
iterate_devices_callout_fn fn, void *data)
{ … }
static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
{ … }
static struct target_type crypt_target = …;
module_dm(crypt);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;