Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.4-rc1 209 lines 6.1 kB view raw
1/* 2 * copied from linux/fs/ext4/crypto_policy.c 3 * 4 * Copyright (C) 2015, Google, Inc. 5 * Copyright (C) 2015, Motorola Mobility. 6 * 7 * This contains encryption policy functions for f2fs with some modifications 8 * to support f2fs-specific xattr APIs. 9 * 10 * Written by Michael Halcrow, 2015. 11 * Modified by Jaegeuk Kim, 2015. 12 */ 13#include <linux/random.h> 14#include <linux/string.h> 15#include <linux/types.h> 16#include <linux/f2fs_fs.h> 17 18#include "f2fs.h" 19#include "xattr.h" 20 21static int f2fs_inode_has_encryption_context(struct inode *inode) 22{ 23 int res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION, 24 F2FS_XATTR_NAME_ENCRYPTION_CONTEXT, NULL, 0, NULL); 25 return (res > 0); 26} 27 28/* 29 * check whether the policy is consistent with the encryption context 30 * for the inode 31 */ 32static int f2fs_is_encryption_context_consistent_with_policy( 33 struct inode *inode, const struct f2fs_encryption_policy *policy) 34{ 35 struct f2fs_encryption_context ctx; 36 int res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION, 37 F2FS_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx, 38 sizeof(ctx), NULL); 39 40 if (res != sizeof(ctx)) 41 return 0; 42 43 return (memcmp(ctx.master_key_descriptor, policy->master_key_descriptor, 44 F2FS_KEY_DESCRIPTOR_SIZE) == 0 && 45 (ctx.flags == policy->flags) && 46 (ctx.contents_encryption_mode == 47 policy->contents_encryption_mode) && 48 (ctx.filenames_encryption_mode == 49 policy->filenames_encryption_mode)); 50} 51 52static int f2fs_create_encryption_context_from_policy( 53 struct inode *inode, const struct f2fs_encryption_policy *policy) 54{ 55 struct f2fs_encryption_context ctx; 56 57 ctx.format = F2FS_ENCRYPTION_CONTEXT_FORMAT_V1; 58 memcpy(ctx.master_key_descriptor, policy->master_key_descriptor, 59 F2FS_KEY_DESCRIPTOR_SIZE); 60 61 if (!f2fs_valid_contents_enc_mode(policy->contents_encryption_mode)) { 62 printk(KERN_WARNING 63 "%s: Invalid contents encryption mode %d\n", __func__, 64 policy->contents_encryption_mode); 65 return -EINVAL; 66 } 67 68 if (!f2fs_valid_filenames_enc_mode(policy->filenames_encryption_mode)) { 69 printk(KERN_WARNING 70 "%s: Invalid filenames encryption mode %d\n", __func__, 71 policy->filenames_encryption_mode); 72 return -EINVAL; 73 } 74 75 if (policy->flags & ~F2FS_POLICY_FLAGS_VALID) 76 return -EINVAL; 77 78 ctx.contents_encryption_mode = policy->contents_encryption_mode; 79 ctx.filenames_encryption_mode = policy->filenames_encryption_mode; 80 ctx.flags = policy->flags; 81 BUILD_BUG_ON(sizeof(ctx.nonce) != F2FS_KEY_DERIVATION_NONCE_SIZE); 82 get_random_bytes(ctx.nonce, F2FS_KEY_DERIVATION_NONCE_SIZE); 83 84 return f2fs_setxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION, 85 F2FS_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx, 86 sizeof(ctx), NULL, XATTR_CREATE); 87} 88 89int f2fs_process_policy(const struct f2fs_encryption_policy *policy, 90 struct inode *inode) 91{ 92 if (policy->version != 0) 93 return -EINVAL; 94 95 if (!S_ISDIR(inode->i_mode)) 96 return -EINVAL; 97 98 if (!f2fs_inode_has_encryption_context(inode)) { 99 if (!f2fs_empty_dir(inode)) 100 return -ENOTEMPTY; 101 return f2fs_create_encryption_context_from_policy(inode, 102 policy); 103 } 104 105 if (f2fs_is_encryption_context_consistent_with_policy(inode, policy)) 106 return 0; 107 108 printk(KERN_WARNING "%s: Policy inconsistent with encryption context\n", 109 __func__); 110 return -EINVAL; 111} 112 113int f2fs_get_policy(struct inode *inode, struct f2fs_encryption_policy *policy) 114{ 115 struct f2fs_encryption_context ctx; 116 int res; 117 118 if (!f2fs_encrypted_inode(inode)) 119 return -ENODATA; 120 121 res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION, 122 F2FS_XATTR_NAME_ENCRYPTION_CONTEXT, 123 &ctx, sizeof(ctx), NULL); 124 if (res != sizeof(ctx)) 125 return -ENODATA; 126 if (ctx.format != F2FS_ENCRYPTION_CONTEXT_FORMAT_V1) 127 return -EINVAL; 128 129 policy->version = 0; 130 policy->contents_encryption_mode = ctx.contents_encryption_mode; 131 policy->filenames_encryption_mode = ctx.filenames_encryption_mode; 132 policy->flags = ctx.flags; 133 memcpy(&policy->master_key_descriptor, ctx.master_key_descriptor, 134 F2FS_KEY_DESCRIPTOR_SIZE); 135 return 0; 136} 137 138int f2fs_is_child_context_consistent_with_parent(struct inode *parent, 139 struct inode *child) 140{ 141 struct f2fs_crypt_info *parent_ci, *child_ci; 142 int res; 143 144 if ((parent == NULL) || (child == NULL)) { 145 pr_err("parent %p child %p\n", parent, child); 146 BUG_ON(1); 147 } 148 149 /* no restrictions if the parent directory is not encrypted */ 150 if (!f2fs_encrypted_inode(parent)) 151 return 1; 152 /* if the child directory is not encrypted, this is always a problem */ 153 if (!f2fs_encrypted_inode(child)) 154 return 0; 155 res = f2fs_get_encryption_info(parent); 156 if (res) 157 return 0; 158 res = f2fs_get_encryption_info(child); 159 if (res) 160 return 0; 161 parent_ci = F2FS_I(parent)->i_crypt_info; 162 child_ci = F2FS_I(child)->i_crypt_info; 163 if (!parent_ci && !child_ci) 164 return 1; 165 if (!parent_ci || !child_ci) 166 return 0; 167 168 return (memcmp(parent_ci->ci_master_key, 169 child_ci->ci_master_key, 170 F2FS_KEY_DESCRIPTOR_SIZE) == 0 && 171 (parent_ci->ci_data_mode == child_ci->ci_data_mode) && 172 (parent_ci->ci_filename_mode == child_ci->ci_filename_mode) && 173 (parent_ci->ci_flags == child_ci->ci_flags)); 174} 175 176/** 177 * f2fs_inherit_context() - Sets a child context from its parent 178 * @parent: Parent inode from which the context is inherited. 179 * @child: Child inode that inherits the context from @parent. 180 * 181 * Return: Zero on success, non-zero otherwise 182 */ 183int f2fs_inherit_context(struct inode *parent, struct inode *child, 184 struct page *ipage) 185{ 186 struct f2fs_encryption_context ctx; 187 struct f2fs_crypt_info *ci; 188 int res; 189 190 res = f2fs_get_encryption_info(parent); 191 if (res < 0) 192 return res; 193 194 ci = F2FS_I(parent)->i_crypt_info; 195 BUG_ON(ci == NULL); 196 197 ctx.format = F2FS_ENCRYPTION_CONTEXT_FORMAT_V1; 198 199 ctx.contents_encryption_mode = ci->ci_data_mode; 200 ctx.filenames_encryption_mode = ci->ci_filename_mode; 201 ctx.flags = ci->ci_flags; 202 memcpy(ctx.master_key_descriptor, ci->ci_master_key, 203 F2FS_KEY_DESCRIPTOR_SIZE); 204 205 get_random_bytes(ctx.nonce, F2FS_KEY_DERIVATION_NONCE_SIZE); 206 return f2fs_setxattr(child, F2FS_XATTR_INDEX_ENCRYPTION, 207 F2FS_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx, 208 sizeof(ctx), ipage, XATTR_CREATE); 209}