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.17-rc3 363 lines 9.8 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * key management facility for FS encryption support. 4 * 5 * Copyright (C) 2015, Google, Inc. 6 * 7 * This contains encryption key functions. 8 * 9 * Written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar, 2015. 10 */ 11 12#include <keys/user-type.h> 13#include <linux/scatterlist.h> 14#include <linux/ratelimit.h> 15#include <crypto/aes.h> 16#include <crypto/sha.h> 17#include <crypto/skcipher.h> 18#include "fscrypt_private.h" 19 20static struct crypto_shash *essiv_hash_tfm; 21 22/** 23 * derive_key_aes() - Derive a key using AES-128-ECB 24 * @deriving_key: Encryption key used for derivation. 25 * @source_key: Source key to which to apply derivation. 26 * @derived_raw_key: Derived raw key. 27 * 28 * Return: Zero on success; non-zero otherwise. 29 */ 30static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], 31 const struct fscrypt_key *source_key, 32 u8 derived_raw_key[FS_MAX_KEY_SIZE]) 33{ 34 int res = 0; 35 struct skcipher_request *req = NULL; 36 DECLARE_CRYPTO_WAIT(wait); 37 struct scatterlist src_sg, dst_sg; 38 struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0); 39 40 if (IS_ERR(tfm)) { 41 res = PTR_ERR(tfm); 42 tfm = NULL; 43 goto out; 44 } 45 crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY); 46 req = skcipher_request_alloc(tfm, GFP_NOFS); 47 if (!req) { 48 res = -ENOMEM; 49 goto out; 50 } 51 skcipher_request_set_callback(req, 52 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 53 crypto_req_done, &wait); 54 res = crypto_skcipher_setkey(tfm, deriving_key, 55 FS_AES_128_ECB_KEY_SIZE); 56 if (res < 0) 57 goto out; 58 59 sg_init_one(&src_sg, source_key->raw, source_key->size); 60 sg_init_one(&dst_sg, derived_raw_key, source_key->size); 61 skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size, 62 NULL); 63 res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 64out: 65 skcipher_request_free(req); 66 crypto_free_skcipher(tfm); 67 return res; 68} 69 70static int validate_user_key(struct fscrypt_info *crypt_info, 71 struct fscrypt_context *ctx, u8 *raw_key, 72 const char *prefix, int min_keysize) 73{ 74 char *description; 75 struct key *keyring_key; 76 struct fscrypt_key *master_key; 77 const struct user_key_payload *ukp; 78 int res; 79 80 description = kasprintf(GFP_NOFS, "%s%*phN", prefix, 81 FS_KEY_DESCRIPTOR_SIZE, 82 ctx->master_key_descriptor); 83 if (!description) 84 return -ENOMEM; 85 86 keyring_key = request_key(&key_type_logon, description, NULL); 87 kfree(description); 88 if (IS_ERR(keyring_key)) 89 return PTR_ERR(keyring_key); 90 down_read(&keyring_key->sem); 91 92 if (keyring_key->type != &key_type_logon) { 93 printk_once(KERN_WARNING 94 "%s: key type must be logon\n", __func__); 95 res = -ENOKEY; 96 goto out; 97 } 98 ukp = user_key_payload_locked(keyring_key); 99 if (!ukp) { 100 /* key was revoked before we acquired its semaphore */ 101 res = -EKEYREVOKED; 102 goto out; 103 } 104 if (ukp->datalen != sizeof(struct fscrypt_key)) { 105 res = -EINVAL; 106 goto out; 107 } 108 master_key = (struct fscrypt_key *)ukp->data; 109 BUILD_BUG_ON(FS_AES_128_ECB_KEY_SIZE != FS_KEY_DERIVATION_NONCE_SIZE); 110 111 if (master_key->size < min_keysize || master_key->size > FS_MAX_KEY_SIZE 112 || master_key->size % AES_BLOCK_SIZE != 0) { 113 printk_once(KERN_WARNING 114 "%s: key size incorrect: %d\n", 115 __func__, master_key->size); 116 res = -ENOKEY; 117 goto out; 118 } 119 res = derive_key_aes(ctx->nonce, master_key, raw_key); 120out: 121 up_read(&keyring_key->sem); 122 key_put(keyring_key); 123 return res; 124} 125 126static const struct { 127 const char *cipher_str; 128 int keysize; 129} available_modes[] = { 130 [FS_ENCRYPTION_MODE_AES_256_XTS] = { "xts(aes)", 131 FS_AES_256_XTS_KEY_SIZE }, 132 [FS_ENCRYPTION_MODE_AES_256_CTS] = { "cts(cbc(aes))", 133 FS_AES_256_CTS_KEY_SIZE }, 134 [FS_ENCRYPTION_MODE_AES_128_CBC] = { "cbc(aes)", 135 FS_AES_128_CBC_KEY_SIZE }, 136 [FS_ENCRYPTION_MODE_AES_128_CTS] = { "cts(cbc(aes))", 137 FS_AES_128_CTS_KEY_SIZE }, 138}; 139 140static int determine_cipher_type(struct fscrypt_info *ci, struct inode *inode, 141 const char **cipher_str_ret, int *keysize_ret) 142{ 143 u32 mode; 144 145 if (!fscrypt_valid_enc_modes(ci->ci_data_mode, ci->ci_filename_mode)) { 146 pr_warn_ratelimited("fscrypt: inode %lu uses unsupported encryption modes (contents mode %d, filenames mode %d)\n", 147 inode->i_ino, 148 ci->ci_data_mode, ci->ci_filename_mode); 149 return -EINVAL; 150 } 151 152 if (S_ISREG(inode->i_mode)) { 153 mode = ci->ci_data_mode; 154 } else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) { 155 mode = ci->ci_filename_mode; 156 } else { 157 WARN_ONCE(1, "fscrypt: filesystem tried to load encryption info for inode %lu, which is not encryptable (file type %d)\n", 158 inode->i_ino, (inode->i_mode & S_IFMT)); 159 return -EINVAL; 160 } 161 162 *cipher_str_ret = available_modes[mode].cipher_str; 163 *keysize_ret = available_modes[mode].keysize; 164 return 0; 165} 166 167static void put_crypt_info(struct fscrypt_info *ci) 168{ 169 if (!ci) 170 return; 171 172 crypto_free_skcipher(ci->ci_ctfm); 173 crypto_free_cipher(ci->ci_essiv_tfm); 174 kmem_cache_free(fscrypt_info_cachep, ci); 175} 176 177static int derive_essiv_salt(const u8 *key, int keysize, u8 *salt) 178{ 179 struct crypto_shash *tfm = READ_ONCE(essiv_hash_tfm); 180 181 /* init hash transform on demand */ 182 if (unlikely(!tfm)) { 183 struct crypto_shash *prev_tfm; 184 185 tfm = crypto_alloc_shash("sha256", 0, 0); 186 if (IS_ERR(tfm)) { 187 pr_warn_ratelimited("fscrypt: error allocating SHA-256 transform: %ld\n", 188 PTR_ERR(tfm)); 189 return PTR_ERR(tfm); 190 } 191 prev_tfm = cmpxchg(&essiv_hash_tfm, NULL, tfm); 192 if (prev_tfm) { 193 crypto_free_shash(tfm); 194 tfm = prev_tfm; 195 } 196 } 197 198 { 199 SHASH_DESC_ON_STACK(desc, tfm); 200 desc->tfm = tfm; 201 desc->flags = 0; 202 203 return crypto_shash_digest(desc, key, keysize, salt); 204 } 205} 206 207static int init_essiv_generator(struct fscrypt_info *ci, const u8 *raw_key, 208 int keysize) 209{ 210 int err; 211 struct crypto_cipher *essiv_tfm; 212 u8 salt[SHA256_DIGEST_SIZE]; 213 214 essiv_tfm = crypto_alloc_cipher("aes", 0, 0); 215 if (IS_ERR(essiv_tfm)) 216 return PTR_ERR(essiv_tfm); 217 218 ci->ci_essiv_tfm = essiv_tfm; 219 220 err = derive_essiv_salt(raw_key, keysize, salt); 221 if (err) 222 goto out; 223 224 /* 225 * Using SHA256 to derive the salt/key will result in AES-256 being 226 * used for IV generation. File contents encryption will still use the 227 * configured keysize (AES-128) nevertheless. 228 */ 229 err = crypto_cipher_setkey(essiv_tfm, salt, sizeof(salt)); 230 if (err) 231 goto out; 232 233out: 234 memzero_explicit(salt, sizeof(salt)); 235 return err; 236} 237 238void __exit fscrypt_essiv_cleanup(void) 239{ 240 crypto_free_shash(essiv_hash_tfm); 241} 242 243int fscrypt_get_encryption_info(struct inode *inode) 244{ 245 struct fscrypt_info *crypt_info; 246 struct fscrypt_context ctx; 247 struct crypto_skcipher *ctfm; 248 const char *cipher_str; 249 int keysize; 250 u8 *raw_key = NULL; 251 int res; 252 253 if (inode->i_crypt_info) 254 return 0; 255 256 res = fscrypt_initialize(inode->i_sb->s_cop->flags); 257 if (res) 258 return res; 259 260 res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx)); 261 if (res < 0) { 262 if (!fscrypt_dummy_context_enabled(inode) || 263 IS_ENCRYPTED(inode)) 264 return res; 265 /* Fake up a context for an unencrypted directory */ 266 memset(&ctx, 0, sizeof(ctx)); 267 ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1; 268 ctx.contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS; 269 ctx.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS; 270 memset(ctx.master_key_descriptor, 0x42, FS_KEY_DESCRIPTOR_SIZE); 271 } else if (res != sizeof(ctx)) { 272 return -EINVAL; 273 } 274 275 if (ctx.format != FS_ENCRYPTION_CONTEXT_FORMAT_V1) 276 return -EINVAL; 277 278 if (ctx.flags & ~FS_POLICY_FLAGS_VALID) 279 return -EINVAL; 280 281 crypt_info = kmem_cache_alloc(fscrypt_info_cachep, GFP_NOFS); 282 if (!crypt_info) 283 return -ENOMEM; 284 285 crypt_info->ci_flags = ctx.flags; 286 crypt_info->ci_data_mode = ctx.contents_encryption_mode; 287 crypt_info->ci_filename_mode = ctx.filenames_encryption_mode; 288 crypt_info->ci_ctfm = NULL; 289 crypt_info->ci_essiv_tfm = NULL; 290 memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor, 291 sizeof(crypt_info->ci_master_key)); 292 293 res = determine_cipher_type(crypt_info, inode, &cipher_str, &keysize); 294 if (res) 295 goto out; 296 297 /* 298 * This cannot be a stack buffer because it is passed to the scatterlist 299 * crypto API as part of key derivation. 300 */ 301 res = -ENOMEM; 302 raw_key = kmalloc(FS_MAX_KEY_SIZE, GFP_NOFS); 303 if (!raw_key) 304 goto out; 305 306 res = validate_user_key(crypt_info, &ctx, raw_key, FS_KEY_DESC_PREFIX, 307 keysize); 308 if (res && inode->i_sb->s_cop->key_prefix) { 309 int res2 = validate_user_key(crypt_info, &ctx, raw_key, 310 inode->i_sb->s_cop->key_prefix, 311 keysize); 312 if (res2) { 313 if (res2 == -ENOKEY) 314 res = -ENOKEY; 315 goto out; 316 } 317 } else if (res) { 318 goto out; 319 } 320 ctfm = crypto_alloc_skcipher(cipher_str, 0, 0); 321 if (!ctfm || IS_ERR(ctfm)) { 322 res = ctfm ? PTR_ERR(ctfm) : -ENOMEM; 323 pr_debug("%s: error %d (inode %lu) allocating crypto tfm\n", 324 __func__, res, inode->i_ino); 325 goto out; 326 } 327 crypt_info->ci_ctfm = ctfm; 328 crypto_skcipher_clear_flags(ctfm, ~0); 329 crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_REQ_WEAK_KEY); 330 /* 331 * if the provided key is longer than keysize, we use the first 332 * keysize bytes of the derived key only 333 */ 334 res = crypto_skcipher_setkey(ctfm, raw_key, keysize); 335 if (res) 336 goto out; 337 338 if (S_ISREG(inode->i_mode) && 339 crypt_info->ci_data_mode == FS_ENCRYPTION_MODE_AES_128_CBC) { 340 res = init_essiv_generator(crypt_info, raw_key, keysize); 341 if (res) { 342 pr_debug("%s: error %d (inode %lu) allocating essiv tfm\n", 343 __func__, res, inode->i_ino); 344 goto out; 345 } 346 } 347 if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) == NULL) 348 crypt_info = NULL; 349out: 350 if (res == -ENOKEY) 351 res = 0; 352 put_crypt_info(crypt_info); 353 kzfree(raw_key); 354 return res; 355} 356EXPORT_SYMBOL(fscrypt_get_encryption_info); 357 358void fscrypt_put_encryption_info(struct inode *inode) 359{ 360 put_crypt_info(inode->i_crypt_info); 361 inode->i_crypt_info = NULL; 362} 363EXPORT_SYMBOL(fscrypt_put_encryption_info);