struct ext4_crypto_ctx *ctx = NULL;
int res = 0;
unsigned long flags;
- struct ext4_encryption_key *key = &EXT4_I(inode)->i_encryption_key;
+ struct ext4_crypt_info *ci = &EXT4_I(inode)->i_crypt_info;
if (!ext4_read_workqueue)
ext4_init_crypto();
/* Allocate a new Crypto API context if we don't already have
* one or if it isn't the right mode. */
- BUG_ON(key->mode == EXT4_ENCRYPTION_MODE_INVALID);
- if (ctx->tfm && (ctx->mode != key->mode)) {
+ BUG_ON(ci->ci_mode == EXT4_ENCRYPTION_MODE_INVALID);
+ if (ctx->tfm && (ctx->mode != ci->ci_mode)) {
crypto_free_tfm(ctx->tfm);
ctx->tfm = NULL;
ctx->mode = EXT4_ENCRYPTION_MODE_INVALID;
}
if (!ctx->tfm) {
- switch (key->mode) {
+ switch (ci->ci_mode) {
case EXT4_ENCRYPTION_MODE_AES_256_XTS:
ctx->tfm = crypto_ablkcipher_tfm(
crypto_alloc_ablkcipher("xts(aes)", 0, 0));
ctx->tfm = NULL;
goto out;
}
- ctx->mode = key->mode;
+ ctx->mode = ci->ci_mode;
}
- BUG_ON(key->size != ext4_encryption_key_size(key->mode));
+ BUG_ON(ci->ci_size != ext4_encryption_key_size(ci->ci_mode));
/* There shouldn't be a bounce page attached to the crypto
* context at this point. */
int res = 0;
BUG_ON(!ctx->tfm);
- BUG_ON(ctx->mode != ei->i_encryption_key.mode);
+ BUG_ON(ctx->mode != ei->i_crypt_info.ci_mode);
if (ctx->mode != EXT4_ENCRYPTION_MODE_AES_256_XTS) {
printk_ratelimited(KERN_ERR
crypto_ablkcipher_clear_flags(atfm, ~0);
crypto_tfm_set_flags(ctx->tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- res = crypto_ablkcipher_setkey(atfm, ei->i_encryption_key.raw,
- ei->i_encryption_key.size);
+ res = crypto_ablkcipher_setkey(atfm, ei->i_crypt_info.ci_raw,
+ ei->i_crypt_info.ci_size);
if (res) {
printk_ratelimited(KERN_ERR
"%s: crypto_ablkcipher_setkey() failed\n",
*ctx = NULL;
}
-/**
- * ext4_search_fname_crypto_ctx() -
- */
-static struct ext4_fname_crypto_ctx *ext4_search_fname_crypto_ctx(
- const struct ext4_encryption_key *key)
-{
- return NULL;
-}
-
/**
* ext4_alloc_fname_crypto_ctx() -
*/
struct ext4_fname_crypto_ctx *ext4_alloc_fname_crypto_ctx(
- const struct ext4_encryption_key *key)
+ const struct ext4_crypt_info *ci)
{
struct ext4_fname_crypto_ctx *ctx;
ctx = kmalloc(sizeof(struct ext4_fname_crypto_ctx), GFP_NOFS);
if (ctx == NULL)
return ERR_PTR(-ENOMEM);
- if (key->mode == EXT4_ENCRYPTION_MODE_INVALID) {
+ if (ci->ci_mode == EXT4_ENCRYPTION_MODE_INVALID) {
/* This will automatically set key mode to invalid
* As enum for ENCRYPTION_MODE_INVALID is zero */
- memset(&ctx->key, 0, sizeof(ctx->key));
+ memset(&ctx->ci, 0, sizeof(ctx->ci));
} else {
- memcpy(&ctx->key, key, sizeof(struct ext4_encryption_key));
+ memcpy(&ctx->ci, ci, sizeof(struct ext4_crypt_info));
}
- ctx->has_valid_key = (EXT4_ENCRYPTION_MODE_INVALID == key->mode)
+ ctx->has_valid_key = (EXT4_ENCRYPTION_MODE_INVALID == ci->ci_mode)
? 0 : 1;
ctx->ctfm_key_is_ready = 0;
ctx->ctfm = NULL;
if (!ext4_has_encryption_key(inode))
ext4_generate_encryption_key(inode);
- /* Get a crypto context based on the key.
- * A new context is allocated if no context matches the requested key.
- */
- ctx = ext4_search_fname_crypto_ctx(&(ei->i_encryption_key));
- if (ctx == NULL)
- ctx = ext4_alloc_fname_crypto_ctx(&(ei->i_encryption_key));
+ /* Get a crypto context based on the key. */
+ ctx = ext4_alloc_fname_crypto_ctx(&(ei->i_crypt_info));
if (IS_ERR(ctx))
return ctx;
ctx->flags = ei->i_crypt_policy_flags;
if (ctx->has_valid_key) {
- if (ctx->key.mode != EXT4_ENCRYPTION_MODE_AES_256_CTS) {
+ if (ctx->ci.ci_mode != EXT4_ENCRYPTION_MODE_AES_256_CTS) {
printk_once(KERN_WARNING
"ext4: unsupported key mode %d\n",
- ctx->key.mode);
+ ctx->ci.ci_mode);
return ERR_PTR(-ENOKEY);
}
* are pretty weak,
* we directly use the inode master key */
res = crypto_ablkcipher_setkey(ctx->ctfm,
- ctx->key.raw, ctx->key.size);
+ ctx->ci.ci_raw, ctx->ci.ci_size);
if (res) {
ext4_put_fname_crypto_ctx(&ctx);
return ERR_PTR(-EIO);
int ext4_generate_encryption_key(struct inode *inode)
{
struct ext4_inode_info *ei = EXT4_I(inode);
- struct ext4_encryption_key *crypt_key = &ei->i_encryption_key;
+ struct ext4_crypt_info *crypt_info = &ei->i_crypt_info;
char full_key_descriptor[EXT4_KEY_DESC_PREFIX_SIZE +
(EXT4_KEY_DESCRIPTOR_SIZE * 2) + 1];
struct key *keyring_key = NULL;
ei->i_crypt_policy_flags = ctx.flags;
if (S_ISREG(inode->i_mode))
- crypt_key->mode = ctx.contents_encryption_mode;
+ crypt_info->ci_mode = ctx.contents_encryption_mode;
else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
- crypt_key->mode = ctx.filenames_encryption_mode;
+ crypt_info->ci_mode = ctx.filenames_encryption_mode;
else {
printk(KERN_ERR "ext4 crypto: Unsupported inode type.\n");
BUG();
}
- crypt_key->size = ext4_encryption_key_size(crypt_key->mode);
- BUG_ON(!crypt_key->size);
+ crypt_info->ci_size = ext4_encryption_key_size(crypt_info->ci_mode);
+ BUG_ON(!crypt_info->ci_size);
if (DUMMY_ENCRYPTION_ENABLED(sbi)) {
- memset(crypt_key->raw, 0x42, EXT4_AES_256_XTS_KEY_SIZE);
+ memset(crypt_info->ci_raw, 0x42, EXT4_AES_256_XTS_KEY_SIZE);
goto out;
}
memcpy(full_key_descriptor, EXT4_KEY_DESC_PREFIX,
BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE !=
EXT4_KEY_DERIVATION_NONCE_SIZE);
BUG_ON(master_key->size != EXT4_AES_256_XTS_KEY_SIZE);
- res = ext4_derive_key_aes(ctx.nonce, master_key->raw, crypt_key->raw);
+ res = ext4_derive_key_aes(ctx.nonce, master_key->raw,
+ crypt_info->ci_raw);
out:
if (keyring_key)
key_put(keyring_key);
if (res < 0)
- crypt_key->mode = EXT4_ENCRYPTION_MODE_INVALID;
+ crypt_info->ci_mode = EXT4_ENCRYPTION_MODE_INVALID;
return res;
}
int ext4_has_encryption_key(struct inode *inode)
{
struct ext4_inode_info *ei = EXT4_I(inode);
- struct ext4_encryption_key *crypt_key = &ei->i_encryption_key;
+ struct ext4_crypt_info *crypt_info = &ei->i_crypt_info;
- return (crypt_key->mode != EXT4_ENCRYPTION_MODE_INVALID);
+ return (crypt_info->ci_mode != EXT4_ENCRYPTION_MODE_INVALID);
}
#ifdef CONFIG_EXT4_FS_ENCRYPTION
/* Encryption params */
- struct ext4_encryption_key i_encryption_key;
+ struct ext4_crypt_info i_crypt_info;
#endif
};
#define EXT4_KEY_DESC_PREFIX "ext4:"
#define EXT4_KEY_DESC_PREFIX_SIZE 5
+/* This is passed in from userspace into the kernel keyring */
struct ext4_encryption_key {
- uint32_t mode;
- char raw[EXT4_MAX_KEY_SIZE];
- uint32_t size;
+ __u32 mode;
+ char raw[EXT4_MAX_KEY_SIZE];
+ __u32 size;
+} __attribute__((__packed__));
+
+struct ext4_crypt_info {
+ unsigned char ci_mode;
+ unsigned char ci_size;
+ char ci_raw[EXT4_MAX_KEY_SIZE];
};
#define EXT4_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
u32 lim;
struct crypto_ablkcipher *ctfm;
struct crypto_hash *htfm;
- struct ext4_encryption_key key;
+ struct ext4_crypt_info ci;
unsigned flags : 8;
unsigned has_valid_key : 1;
unsigned ctfm_key_is_ready : 1;
atomic_set(&ei->i_unwritten, 0);
INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work);
#ifdef CONFIG_EXT4_FS_ENCRYPTION
- ei->i_encryption_key.mode = EXT4_ENCRYPTION_MODE_INVALID;
+ ei->i_crypt_info.ci_mode = EXT4_ENCRYPTION_MODE_INVALID;
#endif
return &ei->vfs_inode;