1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Encryption policy functions for per-file encryption support. 4 * 5 * Copyright (C) 2015, Google, Inc. 6 * Copyright (C) 2015, Motorola Mobility. 7 * 8 * Originally written by Michael Halcrow, 2015. --- 15 unchanged lines hidden (view full) --- 24 const union fscrypt_policy *policy2) 25{ 26 if (policy1->version != policy2->version) 27 return false; 28 29 return !memcmp(policy1, policy2, fscrypt_policy_size(policy1)); 30} 31 |
32static bool fscrypt_valid_enc_modes(u32 contents_mode, u32 filenames_mode) 33{ 34 if (contents_mode == FSCRYPT_MODE_AES_256_XTS && 35 filenames_mode == FSCRYPT_MODE_AES_256_CTS) 36 return true; 37 38 if (contents_mode == FSCRYPT_MODE_AES_128_CBC && 39 filenames_mode == FSCRYPT_MODE_AES_128_CTS) 40 return true; 41 42 if (contents_mode == FSCRYPT_MODE_ADIANTUM && 43 filenames_mode == FSCRYPT_MODE_ADIANTUM) 44 return true; 45 46 return false; 47} 48 49static bool supported_direct_key_modes(const struct inode *inode, 50 u32 contents_mode, u32 filenames_mode) 51{ 52 const struct fscrypt_mode *mode; 53 54 if (contents_mode != filenames_mode) { 55 fscrypt_warn(inode, 56 "Direct key flag not allowed with different contents and filenames modes"); 57 return false; 58 } 59 mode = &fscrypt_modes[contents_mode]; 60 61 if (mode->ivsize < offsetofend(union fscrypt_iv, nonce)) { 62 fscrypt_warn(inode, "Direct key flag not allowed with %s", 63 mode->friendly_name); 64 return false; 65 } 66 return true; 67} 68 |
69static bool supported_iv_ino_lblk_64_policy( 70 const struct fscrypt_policy_v2 *policy, 71 const struct inode *inode) 72{ 73 struct super_block *sb = inode->i_sb; 74 int ino_bits = 64, lblk_bits = 64; 75 76 if (policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) { --- 18 unchanged lines hidden (view full) --- 95 fscrypt_warn(inode, 96 "Can't use IV_INO_LBLK_64 policy on filesystem '%s' because it doesn't use 32-bit inode and block numbers", 97 sb->s_id); 98 return false; 99 } 100 return true; 101} 102 |
103static bool fscrypt_supported_v1_policy(const struct fscrypt_policy_v1 *policy, 104 const struct inode *inode) 105{ 106 if (!fscrypt_valid_enc_modes(policy->contents_encryption_mode, 107 policy->filenames_encryption_mode)) { 108 fscrypt_warn(inode, 109 "Unsupported encryption modes (contents %d, filenames %d)", 110 policy->contents_encryption_mode, 111 policy->filenames_encryption_mode); 112 return false; 113 } 114 115 if (policy->flags & ~(FSCRYPT_POLICY_FLAGS_PAD_MASK | 116 FSCRYPT_POLICY_FLAG_DIRECT_KEY)) { 117 fscrypt_warn(inode, "Unsupported encryption flags (0x%02x)", 118 policy->flags); 119 return false; 120 } 121 122 if ((policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) && 123 !supported_direct_key_modes(inode, policy->contents_encryption_mode, 124 policy->filenames_encryption_mode)) 125 return false; 126 127 if (IS_CASEFOLDED(inode)) { 128 /* With v1, there's no way to derive dirhash keys. */ 129 fscrypt_warn(inode, 130 "v1 policies can't be used on casefolded directories"); 131 return false; 132 } 133 134 return true; 135} 136 137static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy, 138 const struct inode *inode) 139{ 140 if (!fscrypt_valid_enc_modes(policy->contents_encryption_mode, 141 policy->filenames_encryption_mode)) { 142 fscrypt_warn(inode, 143 "Unsupported encryption modes (contents %d, filenames %d)", 144 policy->contents_encryption_mode, 145 policy->filenames_encryption_mode); 146 return false; 147 } 148 149 if (policy->flags & ~FSCRYPT_POLICY_FLAGS_VALID) { 150 fscrypt_warn(inode, "Unsupported encryption flags (0x%02x)", 151 policy->flags); 152 return false; 153 } 154 155 if ((policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) && 156 !supported_direct_key_modes(inode, policy->contents_encryption_mode, 157 policy->filenames_encryption_mode)) 158 return false; 159 160 if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) && 161 !supported_iv_ino_lblk_64_policy(policy, inode)) 162 return false; 163 164 if (memchr_inv(policy->__reserved, 0, sizeof(policy->__reserved))) { 165 fscrypt_warn(inode, "Reserved bits set in encryption policy"); 166 return false; 167 } 168 169 return true; 170} 171 |
172/** 173 * fscrypt_supported_policy - check whether an encryption policy is supported 174 * 175 * Given an encryption policy, check whether all its encryption modes and other |
176 * settings are supported by this kernel on the given inode. (But we don't 177 * currently don't check for crypto API support here, so attempting to use an 178 * algorithm not configured into the crypto API will still fail later.) |
179 * 180 * Return: %true if supported, else %false 181 */ 182bool fscrypt_supported_policy(const union fscrypt_policy *policy_u, 183 const struct inode *inode) 184{ 185 switch (policy_u->version) { |
186 case FSCRYPT_POLICY_V1: 187 return fscrypt_supported_v1_policy(&policy_u->v1, inode); 188 case FSCRYPT_POLICY_V2: 189 return fscrypt_supported_v2_policy(&policy_u->v2, inode); |
190 } |
191 return false; 192} 193 194/** 195 * fscrypt_new_context_from_policy - create a new fscrypt_context from a policy 196 * 197 * Create an fscrypt_context for an inode that is being assigned the given 198 * encryption policy. A new nonce is randomly generated. --- 390 unchanged lines hidden --- |