diff options
-rw-r--r-- | fs/ext4/crypto.c | 18 | ||||
-rw-r--r-- | fs/ext4/crypto_fname.c | 33 | ||||
-rw-r--r-- | fs/ext4/crypto_key.c | 21 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 2 | ||||
-rw-r--r-- | fs/ext4/ext4_crypto.h | 15 | ||||
-rw-r--r-- | fs/ext4/super.c | 2 |
6 files changed, 43 insertions, 48 deletions
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c index 8ff15273ab0c..918200ed9bf8 100644 --- a/fs/ext4/crypto.c +++ b/fs/ext4/crypto.c @@ -118,7 +118,7 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode) 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(); @@ -152,14 +152,14 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode) /* 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)); @@ -177,9 +177,9 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode) 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. */ @@ -322,7 +322,7 @@ static int ext4_page_crypto(struct ext4_crypto_ctx *ctx, 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 @@ -334,8 +334,8 @@ static int ext4_page_crypto(struct ext4_crypto_ctx *ctx, 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", diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c index 23d7f1d56b00..d9f08ddbfda2 100644 --- a/fs/ext4/crypto_fname.c +++ b/fs/ext4/crypto_fname.c @@ -278,33 +278,24 @@ void ext4_put_fname_crypto_ctx(struct ext4_fname_crypto_ctx **ctx) } /** - * 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; @@ -335,21 +326,17 @@ struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx( 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); } @@ -389,7 +376,7 @@ struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx( * 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); diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c index 52170d0b7c40..ec6635dc50f9 100644 --- a/fs/ext4/crypto_key.c +++ b/fs/ext4/crypto_key.c @@ -91,7 +91,7 @@ out: 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; @@ -112,17 +112,17 @@ int ext4_generate_encryption_key(struct inode *inode) 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, @@ -148,19 +148,20 @@ int ext4_generate_encryption_key(struct inode *inode) 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); } diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 866831e7c136..3cf3bcb6b239 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -955,7 +955,7 @@ struct ext4_inode_info { #ifdef CONFIG_EXT4_FS_ENCRYPTION /* Encryption params */ - struct ext4_encryption_key i_encryption_key; + struct ext4_crypt_info i_crypt_info; #endif }; diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h index 552424ae3ab3..deecbe8968d1 100644 --- a/fs/ext4/ext4_crypto.h +++ b/fs/ext4/ext4_crypto.h @@ -66,10 +66,17 @@ struct ext4_encryption_context { #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 @@ -125,7 +132,7 @@ struct ext4_fname_crypto_ctx { 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; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ca9d4a2fed41..bcd7a4bc9036 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -879,7 +879,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) 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; |