root/fs/crypto/keysetup_v1.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. derive_key_aes
  2. find_and_lock_process_key
  3. free_direct_key
  4. fscrypt_put_direct_key
  5. find_or_insert_direct_key
  6. fscrypt_get_direct_key
  7. setup_v1_file_key_direct
  8. setup_v1_file_key_derived
  9. fscrypt_setup_v1_file_key
  10. fscrypt_setup_v1_file_key_via_subscribed_keyrings

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Key setup for v1 encryption policies
   4  *
   5  * Copyright 2015, 2019 Google LLC
   6  */
   7 
   8 /*
   9  * This file implements compatibility functions for the original encryption
  10  * policy version ("v1"), including:
  11  *
  12  * - Deriving per-file keys using the AES-128-ECB based KDF
  13  *   (rather than the new method of using HKDF-SHA512)
  14  *
  15  * - Retrieving fscrypt master keys from process-subscribed keyrings
  16  *   (rather than the new method of using a filesystem-level keyring)
  17  *
  18  * - Handling policies with the DIRECT_KEY flag set using a master key table
  19  *   (rather than the new method of implementing DIRECT_KEY with per-mode keys
  20  *    managed alongside the master keys in the filesystem-level keyring)
  21  */
  22 
  23 #include <crypto/algapi.h>
  24 #include <crypto/skcipher.h>
  25 #include <keys/user-type.h>
  26 #include <linux/hashtable.h>
  27 #include <linux/scatterlist.h>
  28 
  29 #include "fscrypt_private.h"
  30 
  31 /* Table of keys referenced by DIRECT_KEY policies */
  32 static DEFINE_HASHTABLE(fscrypt_direct_keys, 6); /* 6 bits = 64 buckets */
  33 static DEFINE_SPINLOCK(fscrypt_direct_keys_lock);
  34 
  35 /*
  36  * v1 key derivation function.  This generates the derived key by encrypting the
  37  * master key with AES-128-ECB using the nonce as the AES key.  This provides a
  38  * unique derived key with sufficient entropy for each inode.  However, it's
  39  * nonstandard, non-extensible, doesn't evenly distribute the entropy from the
  40  * master key, and is trivially reversible: an attacker who compromises a
  41  * derived key can "decrypt" it to get back to the master key, then derive any
  42  * other key.  For all new code, use HKDF instead.
  43  *
  44  * The master key must be at least as long as the derived key.  If the master
  45  * key is longer, then only the first 'derived_keysize' bytes are used.
  46  */
  47 static int derive_key_aes(const u8 *master_key,
  48                           const u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE],
  49                           u8 *derived_key, unsigned int derived_keysize)
  50 {
  51         int res = 0;
  52         struct skcipher_request *req = NULL;
  53         DECLARE_CRYPTO_WAIT(wait);
  54         struct scatterlist src_sg, dst_sg;
  55         struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
  56 
  57         if (IS_ERR(tfm)) {
  58                 res = PTR_ERR(tfm);
  59                 tfm = NULL;
  60                 goto out;
  61         }
  62         crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
  63         req = skcipher_request_alloc(tfm, GFP_NOFS);
  64         if (!req) {
  65                 res = -ENOMEM;
  66                 goto out;
  67         }
  68         skcipher_request_set_callback(req,
  69                         CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
  70                         crypto_req_done, &wait);
  71         res = crypto_skcipher_setkey(tfm, nonce, FS_KEY_DERIVATION_NONCE_SIZE);
  72         if (res < 0)
  73                 goto out;
  74 
  75         sg_init_one(&src_sg, master_key, derived_keysize);
  76         sg_init_one(&dst_sg, derived_key, derived_keysize);
  77         skcipher_request_set_crypt(req, &src_sg, &dst_sg, derived_keysize,
  78                                    NULL);
  79         res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
  80 out:
  81         skcipher_request_free(req);
  82         crypto_free_skcipher(tfm);
  83         return res;
  84 }
  85 
  86 /*
  87  * Search the current task's subscribed keyrings for a "logon" key with
  88  * description prefix:descriptor, and if found acquire a read lock on it and
  89  * return a pointer to its validated payload in *payload_ret.
  90  */
  91 static struct key *
  92 find_and_lock_process_key(const char *prefix,
  93                           const u8 descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE],
  94                           unsigned int min_keysize,
  95                           const struct fscrypt_key **payload_ret)
  96 {
  97         char *description;
  98         struct key *key;
  99         const struct user_key_payload *ukp;
 100         const struct fscrypt_key *payload;
 101 
 102         description = kasprintf(GFP_NOFS, "%s%*phN", prefix,
 103                                 FSCRYPT_KEY_DESCRIPTOR_SIZE, descriptor);
 104         if (!description)
 105                 return ERR_PTR(-ENOMEM);
 106 
 107         key = request_key(&key_type_logon, description, NULL);
 108         kfree(description);
 109         if (IS_ERR(key))
 110                 return key;
 111 
 112         down_read(&key->sem);
 113         ukp = user_key_payload_locked(key);
 114 
 115         if (!ukp) /* was the key revoked before we acquired its semaphore? */
 116                 goto invalid;
 117 
 118         payload = (const struct fscrypt_key *)ukp->data;
 119 
 120         if (ukp->datalen != sizeof(struct fscrypt_key) ||
 121             payload->size < 1 || payload->size > FSCRYPT_MAX_KEY_SIZE) {
 122                 fscrypt_warn(NULL,
 123                              "key with description '%s' has invalid payload",
 124                              key->description);
 125                 goto invalid;
 126         }
 127 
 128         if (payload->size < min_keysize) {
 129                 fscrypt_warn(NULL,
 130                              "key with description '%s' is too short (got %u bytes, need %u+ bytes)",
 131                              key->description, payload->size, min_keysize);
 132                 goto invalid;
 133         }
 134 
 135         *payload_ret = payload;
 136         return key;
 137 
 138 invalid:
 139         up_read(&key->sem);
 140         key_put(key);
 141         return ERR_PTR(-ENOKEY);
 142 }
 143 
 144 /* Master key referenced by DIRECT_KEY policy */
 145 struct fscrypt_direct_key {
 146         struct hlist_node               dk_node;
 147         refcount_t                      dk_refcount;
 148         const struct fscrypt_mode       *dk_mode;
 149         struct crypto_skcipher          *dk_ctfm;
 150         u8                              dk_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
 151         u8                              dk_raw[FSCRYPT_MAX_KEY_SIZE];
 152 };
 153 
 154 static void free_direct_key(struct fscrypt_direct_key *dk)
 155 {
 156         if (dk) {
 157                 crypto_free_skcipher(dk->dk_ctfm);
 158                 kzfree(dk);
 159         }
 160 }
 161 
 162 void fscrypt_put_direct_key(struct fscrypt_direct_key *dk)
 163 {
 164         if (!refcount_dec_and_lock(&dk->dk_refcount, &fscrypt_direct_keys_lock))
 165                 return;
 166         hash_del(&dk->dk_node);
 167         spin_unlock(&fscrypt_direct_keys_lock);
 168 
 169         free_direct_key(dk);
 170 }
 171 
 172 /*
 173  * Find/insert the given key into the fscrypt_direct_keys table.  If found, it
 174  * is returned with elevated refcount, and 'to_insert' is freed if non-NULL.  If
 175  * not found, 'to_insert' is inserted and returned if it's non-NULL; otherwise
 176  * NULL is returned.
 177  */
 178 static struct fscrypt_direct_key *
 179 find_or_insert_direct_key(struct fscrypt_direct_key *to_insert,
 180                           const u8 *raw_key, const struct fscrypt_info *ci)
 181 {
 182         unsigned long hash_key;
 183         struct fscrypt_direct_key *dk;
 184 
 185         /*
 186          * Careful: to avoid potentially leaking secret key bytes via timing
 187          * information, we must key the hash table by descriptor rather than by
 188          * raw key, and use crypto_memneq() when comparing raw keys.
 189          */
 190 
 191         BUILD_BUG_ON(sizeof(hash_key) > FSCRYPT_KEY_DESCRIPTOR_SIZE);
 192         memcpy(&hash_key, ci->ci_policy.v1.master_key_descriptor,
 193                sizeof(hash_key));
 194 
 195         spin_lock(&fscrypt_direct_keys_lock);
 196         hash_for_each_possible(fscrypt_direct_keys, dk, dk_node, hash_key) {
 197                 if (memcmp(ci->ci_policy.v1.master_key_descriptor,
 198                            dk->dk_descriptor, FSCRYPT_KEY_DESCRIPTOR_SIZE) != 0)
 199                         continue;
 200                 if (ci->ci_mode != dk->dk_mode)
 201                         continue;
 202                 if (crypto_memneq(raw_key, dk->dk_raw, ci->ci_mode->keysize))
 203                         continue;
 204                 /* using existing tfm with same (descriptor, mode, raw_key) */
 205                 refcount_inc(&dk->dk_refcount);
 206                 spin_unlock(&fscrypt_direct_keys_lock);
 207                 free_direct_key(to_insert);
 208                 return dk;
 209         }
 210         if (to_insert)
 211                 hash_add(fscrypt_direct_keys, &to_insert->dk_node, hash_key);
 212         spin_unlock(&fscrypt_direct_keys_lock);
 213         return to_insert;
 214 }
 215 
 216 /* Prepare to encrypt directly using the master key in the given mode */
 217 static struct fscrypt_direct_key *
 218 fscrypt_get_direct_key(const struct fscrypt_info *ci, const u8 *raw_key)
 219 {
 220         struct fscrypt_direct_key *dk;
 221         int err;
 222 
 223         /* Is there already a tfm for this key? */
 224         dk = find_or_insert_direct_key(NULL, raw_key, ci);
 225         if (dk)
 226                 return dk;
 227 
 228         /* Nope, allocate one. */
 229         dk = kzalloc(sizeof(*dk), GFP_NOFS);
 230         if (!dk)
 231                 return ERR_PTR(-ENOMEM);
 232         refcount_set(&dk->dk_refcount, 1);
 233         dk->dk_mode = ci->ci_mode;
 234         dk->dk_ctfm = fscrypt_allocate_skcipher(ci->ci_mode, raw_key,
 235                                                 ci->ci_inode);
 236         if (IS_ERR(dk->dk_ctfm)) {
 237                 err = PTR_ERR(dk->dk_ctfm);
 238                 dk->dk_ctfm = NULL;
 239                 goto err_free_dk;
 240         }
 241         memcpy(dk->dk_descriptor, ci->ci_policy.v1.master_key_descriptor,
 242                FSCRYPT_KEY_DESCRIPTOR_SIZE);
 243         memcpy(dk->dk_raw, raw_key, ci->ci_mode->keysize);
 244 
 245         return find_or_insert_direct_key(dk, raw_key, ci);
 246 
 247 err_free_dk:
 248         free_direct_key(dk);
 249         return ERR_PTR(err);
 250 }
 251 
 252 /* v1 policy, DIRECT_KEY: use the master key directly */
 253 static int setup_v1_file_key_direct(struct fscrypt_info *ci,
 254                                     const u8 *raw_master_key)
 255 {
 256         const struct fscrypt_mode *mode = ci->ci_mode;
 257         struct fscrypt_direct_key *dk;
 258 
 259         if (!fscrypt_mode_supports_direct_key(mode)) {
 260                 fscrypt_warn(ci->ci_inode,
 261                              "Direct key mode not allowed with %s",
 262                              mode->friendly_name);
 263                 return -EINVAL;
 264         }
 265 
 266         if (ci->ci_policy.v1.contents_encryption_mode !=
 267             ci->ci_policy.v1.filenames_encryption_mode) {
 268                 fscrypt_warn(ci->ci_inode,
 269                              "Direct key mode not allowed with different contents and filenames modes");
 270                 return -EINVAL;
 271         }
 272 
 273         /* ESSIV implies 16-byte IVs which implies !DIRECT_KEY */
 274         if (WARN_ON(mode->needs_essiv))
 275                 return -EINVAL;
 276 
 277         dk = fscrypt_get_direct_key(ci, raw_master_key);
 278         if (IS_ERR(dk))
 279                 return PTR_ERR(dk);
 280         ci->ci_direct_key = dk;
 281         ci->ci_ctfm = dk->dk_ctfm;
 282         return 0;
 283 }
 284 
 285 /* v1 policy, !DIRECT_KEY: derive the file's encryption key */
 286 static int setup_v1_file_key_derived(struct fscrypt_info *ci,
 287                                      const u8 *raw_master_key)
 288 {
 289         u8 *derived_key;
 290         int err;
 291 
 292         /*
 293          * This cannot be a stack buffer because it will be passed to the
 294          * scatterlist crypto API during derive_key_aes().
 295          */
 296         derived_key = kmalloc(ci->ci_mode->keysize, GFP_NOFS);
 297         if (!derived_key)
 298                 return -ENOMEM;
 299 
 300         err = derive_key_aes(raw_master_key, ci->ci_nonce,
 301                              derived_key, ci->ci_mode->keysize);
 302         if (err)
 303                 goto out;
 304 
 305         err = fscrypt_set_derived_key(ci, derived_key);
 306 out:
 307         kzfree(derived_key);
 308         return err;
 309 }
 310 
 311 int fscrypt_setup_v1_file_key(struct fscrypt_info *ci, const u8 *raw_master_key)
 312 {
 313         if (ci->ci_policy.v1.flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY)
 314                 return setup_v1_file_key_direct(ci, raw_master_key);
 315         else
 316                 return setup_v1_file_key_derived(ci, raw_master_key);
 317 }
 318 
 319 int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_info *ci)
 320 {
 321         struct key *key;
 322         const struct fscrypt_key *payload;
 323         int err;
 324 
 325         key = find_and_lock_process_key(FSCRYPT_KEY_DESC_PREFIX,
 326                                         ci->ci_policy.v1.master_key_descriptor,
 327                                         ci->ci_mode->keysize, &payload);
 328         if (key == ERR_PTR(-ENOKEY) && ci->ci_inode->i_sb->s_cop->key_prefix) {
 329                 key = find_and_lock_process_key(ci->ci_inode->i_sb->s_cop->key_prefix,
 330                                                 ci->ci_policy.v1.master_key_descriptor,
 331                                                 ci->ci_mode->keysize, &payload);
 332         }
 333         if (IS_ERR(key))
 334                 return PTR_ERR(key);
 335 
 336         err = fscrypt_setup_v1_file_key(ci, payload->raw);
 337         up_read(&key->sem);
 338         key_put(key);
 339         return err;
 340 }

/* [<][>][^][v][top][bottom][index][help] */