Skip to content

Commit

Permalink
fscrypt: make test_dummy_encryption require a keyring key
Browse files Browse the repository at this point in the history
Currently, the test_dummy_encryption ext4 mount option, which exists
only to test encrypted I/O paths with xfstests, overrides all
per-inode encryption keys with a fixed key.

This change minimizes test_dummy_encryption-specific code path changes
by supplying a fake context for directories which are not encrypted
for use when creating new directories, files, or symlinks.  This
allows us to properly exercise the keyring lookup, derivation, and
context inheritance code paths.

Before mounting a file system using test_dummy_encryption, userspace
must execute the following shell commands:

    mode='\x00\x00\x00\x00'
    raw="$(printf ""\\\\x%02x"" $(seq 0 63))"
    if lscpu | grep "Byte Order" | grep -q Little ; then
        size='\x40\x00\x00\x00'
    else
        size='\x00\x00\x00\x40'
    fi
    key="${mode}${raw}${size}"
    keyctl new_session
    echo -n -e "${key}" | keyctl padd logon fscrypt:4242424242424242 @s

Signed-off-by: Theodore Ts'o <[email protected]>
  • Loading branch information
tytso committed Jan 2, 2017
1 parent 58ae746 commit 5bbdcbb
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 24 deletions.
15 changes: 6 additions & 9 deletions fs/crypto/keyinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,16 @@ int fscrypt_get_crypt_info(struct inode *inode)

res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
if (res < 0) {
if (!fscrypt_dummy_context_enabled(inode))
if (!fscrypt_dummy_context_enabled(inode) ||
inode->i_sb->s_cop->is_encrypted(inode))
return res;
/* Fake up a context for an unencrypted directory */
memset(&ctx, 0, sizeof(ctx));
ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
ctx.contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS;
ctx.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS;
ctx.flags = 0;
memset(ctx.master_key_descriptor, 0x42, FS_KEY_DESCRIPTOR_SIZE);
res = sizeof(ctx);
} else if (res != sizeof(ctx)) {
return -EINVAL;
}
Expand Down Expand Up @@ -247,12 +251,6 @@ int fscrypt_get_crypt_info(struct inode *inode)
if (!raw_key)
goto out;

if (fscrypt_dummy_context_enabled(inode)) {
memset(raw_key, 0x42, keysize/2);
memset(raw_key+keysize/2, 0x24, keysize - (keysize/2));
goto got_key;
}

res = validate_user_key(crypt_info, &ctx, raw_key,
FS_KEY_DESC_PREFIX, FS_KEY_DESC_PREFIX_SIZE);
if (res && inode->i_sb->s_cop->key_prefix) {
Expand All @@ -270,7 +268,6 @@ int fscrypt_get_crypt_info(struct inode *inode)
} else if (res) {
goto out;
}
got_key:
ctfm = crypto_alloc_skcipher(cipher_str, 0, 0);
if (!ctfm || IS_ERR(ctfm)) {
res = ctfm ? PTR_ERR(ctfm) : -ENOMEM;
Expand Down
22 changes: 7 additions & 15 deletions fs/crypto/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ EXPORT_SYMBOL(fscrypt_has_permitted_context);
* @parent: Parent inode from which the context is inherited.
* @child: Child inode that inherits the context from @parent.
* @fs_data: private data given by FS.
* @preload: preload child i_crypt_info
* @preload: preload child i_crypt_info if true
*
* Return: Zero on success, non-zero otherwise
* Return: 0 on success, -errno on failure
*/
int fscrypt_inherit_context(struct inode *parent, struct inode *child,
void *fs_data, bool preload)
Expand All @@ -221,19 +221,11 @@ int fscrypt_inherit_context(struct inode *parent, struct inode *child,
return -ENOKEY;

ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
if (fscrypt_dummy_context_enabled(parent)) {
ctx.contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS;
ctx.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS;
ctx.flags = 0;
memset(ctx.master_key_descriptor, 0x42, FS_KEY_DESCRIPTOR_SIZE);
res = 0;
} else {
ctx.contents_encryption_mode = ci->ci_data_mode;
ctx.filenames_encryption_mode = ci->ci_filename_mode;
ctx.flags = ci->ci_flags;
memcpy(ctx.master_key_descriptor, ci->ci_master_key,
FS_KEY_DESCRIPTOR_SIZE);
}
ctx.contents_encryption_mode = ci->ci_data_mode;
ctx.filenames_encryption_mode = ci->ci_filename_mode;
ctx.flags = ci->ci_flags;
memcpy(ctx.master_key_descriptor, ci->ci_master_key,
FS_KEY_DESCRIPTOR_SIZE);
get_random_bytes(ctx.nonce, FS_KEY_DERIVATION_NONCE_SIZE);
res = parent->i_sb->s_cop->set_context(child, &ctx,
sizeof(ctx), fs_data);
Expand Down

0 comments on commit 5bbdcbb

Please sign in to comment.