/* SPDX-License-Identifier: GPL-2.0 */ /* * llcrypt_private.h * * Copyright (C) 2015, Google, Inc. * * Originally written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar. * Heavily modified since then. */ /* * Linux commit 219d54332a09 * tags/v5.4 */ #ifndef _LLCRYPT_PRIVATE_H #define _LLCRYPT_PRIVATE_H #include #include #include #ifndef CRYPTO_TFM_REQ_FORBID_WEAK_KEYS #define CRYPTO_TFM_REQ_FORBID_WEAK_KEYS CRYPTO_TFM_REQ_WEAK_KEY #endif #define llcrypt_info(inode) ((struct llcrypt_info *)(inode)->i_private) #define llcrypt_info_nocast(inode) ((inode)->i_private) #define CONST_STRLEN(str) (sizeof(str) - 1) #define FS_KEY_DERIVATION_NONCE_SIZE 16 #define LLCRYPT_MIN_KEY_SIZE 16 #define LLCRYPT_CONTEXT_V1 1 #define LLCRYPT_CONTEXT_V2 2 struct llcrypt_context_v1 { u8 version; /* LLCRYPT_CONTEXT_V1 */ u8 contents_encryption_mode; u8 filenames_encryption_mode; u8 flags; u8 master_key_descriptor[LLCRYPT_KEY_DESCRIPTOR_SIZE]; u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE]; }; struct llcrypt_context_v2 { u8 version; /* LLCRYPT_CONTEXT_V2 */ u8 contents_encryption_mode; u8 filenames_encryption_mode; u8 flags; u8 __reserved[4]; u8 master_key_identifier[LLCRYPT_KEY_IDENTIFIER_SIZE]; u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE]; }; /** * llcrypt_context - the encryption context of an inode * * This is the on-disk equivalent of an llcrypt_policy, stored alongside each * encrypted file usually in a hidden extended attribute. It contains the * fields from the llcrypt_policy, in order to identify the encryption algorithm * and key with which the file is encrypted. It also contains a nonce that was * randomly generated by llcrypt itself; this is used as KDF input or as a tweak * to cause different files to be encrypted differently. */ union llcrypt_context { u8 version; struct llcrypt_context_v1 v1; struct llcrypt_context_v2 v2; }; /* * Return the size expected for the given llcrypt_context based on its version * number, or 0 if the context version is unrecognized. */ static inline int llcrypt_context_size(const union llcrypt_context *ctx) { switch (ctx->version) { case LLCRYPT_CONTEXT_V1: BUILD_BUG_ON(sizeof(ctx->v1) != 28); return sizeof(ctx->v1); case LLCRYPT_CONTEXT_V2: BUILD_BUG_ON(sizeof(ctx->v2) != 40); return sizeof(ctx->v2); } return 0; } #undef llcrypt_policy union llcrypt_policy { u8 version; struct llcrypt_policy_v1 v1; struct llcrypt_policy_v2 v2; }; /* * Return the size expected for the given llcrypt_policy based on its version * number, or 0 if the policy version is unrecognized. */ static inline int llcrypt_policy_size(const union llcrypt_policy *policy) { switch (policy->version) { case LLCRYPT_POLICY_V1: return sizeof(policy->v1); case LLCRYPT_POLICY_V2: return sizeof(policy->v2); } return 0; } /* Return the contents encryption mode of a valid encryption policy */ static inline u8 llcrypt_policy_contents_mode(const union llcrypt_policy *policy) { switch (policy->version) { case LLCRYPT_POLICY_V1: return policy->v1.contents_encryption_mode; case LLCRYPT_POLICY_V2: return policy->v2.contents_encryption_mode; } BUG(); } /* Return the filenames encryption mode of a valid encryption policy */ static inline u8 llcrypt_policy_fnames_mode(const union llcrypt_policy *policy) { switch (policy->version) { case LLCRYPT_POLICY_V1: return policy->v1.filenames_encryption_mode; case LLCRYPT_POLICY_V2: return policy->v2.filenames_encryption_mode; } BUG(); } /* Return the flags (LLCRYPT_POLICY_FLAG*) of a valid encryption policy */ static inline u8 llcrypt_policy_flags(const union llcrypt_policy *policy) { switch (policy->version) { case LLCRYPT_POLICY_V1: return policy->v1.flags; case LLCRYPT_POLICY_V2: return policy->v2.flags; } BUG(); } static inline bool llcrypt_is_direct_key_policy(const union llcrypt_policy *policy) { return llcrypt_policy_flags(policy) & LLCRYPT_POLICY_FLAG_DIRECT_KEY; } /** * For encrypted symlinks, the ciphertext length is stored at the beginning * of the string in little-endian format. */ struct llcrypt_symlink_data { __le16 len; char encrypted_path[1]; } __packed; /* * llcrypt_info - the "encryption key" for an inode * * When an encrypted file's key is made available, an instance of this struct is * allocated and stored in '(struct llcrypt_info *)inode->i_private'. * Once created, it remains until the inode is evicted. */ struct llcrypt_info { /* The actual crypto transform used for encryption and decryption */ struct crypto_skcipher *ci_ctfm; /* * Cipher for ESSIV IV generation. Only set for CBC contents * encryption, otherwise is NULL. */ struct crypto_cipher *ci_essiv_tfm; /* * Encryption mode used for this inode. It corresponds to either the * contents or filenames encryption mode, depending on the inode type. */ struct llcrypt_mode *ci_mode; /* Back-pointer to the inode */ struct inode *ci_inode; /* * The master key with which this inode was unlocked (decrypted). This * will be NULL if the master key was found in a process-subscribed * keyring rather than in the filesystem-level keyring. */ struct key *ci_master_key; /* * Link in list of inodes that were unlocked with the master key. * Only used when ->ci_master_key is set. */ struct list_head ci_master_key_link; /* * If non-NULL, then encryption is done using the master key directly * and ci_ctfm will equal ci_direct_key->dk_ctfm. */ struct llcrypt_direct_key *ci_direct_key; /* The encryption policy used by this inode */ union llcrypt_policy ci_policy; /* This inode's nonce, copied from the llcrypt_context */ u8 ci_nonce[FS_KEY_DERIVATION_NONCE_SIZE]; }; typedef enum { FS_DECRYPT = 0, FS_ENCRYPT, } llcrypt_direction_t; #define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001 static inline bool llcrypt_valid_enc_modes(u32 contents_mode, u32 filenames_mode) { if (contents_mode == LLCRYPT_MODE_AES_128_CBC && (filenames_mode == LLCRYPT_MODE_AES_128_CTS || filenames_mode == LLCRYPT_MODE_NULL)) return true; if (contents_mode == LLCRYPT_MODE_AES_256_XTS && (filenames_mode == LLCRYPT_MODE_AES_256_CTS || filenames_mode == LLCRYPT_MODE_NULL)) return true; if (contents_mode == LLCRYPT_MODE_ADIANTUM && (filenames_mode == LLCRYPT_MODE_ADIANTUM || filenames_mode == LLCRYPT_MODE_NULL)) return true; return false; } /* crypto.c */ extern struct kmem_cache *llcrypt_info_cachep; extern int llcrypt_initialize(unsigned int cop_flags); extern int llcrypt_crypt_block(const struct inode *inode, llcrypt_direction_t rw, u64 lblk_num, struct page *src_page, struct page *dest_page, unsigned int len, unsigned int offs, gfp_t gfp_flags); extern struct page *llcrypt_alloc_bounce_page(gfp_t gfp_flags); extern const struct dentry_operations llcrypt_d_ops; extern void __printf(3, 4) __cold llcrypt_msg(const struct inode *inode, int mask, const char *fmt, ...); #define llcrypt_warn(inode, fmt, ...) \ llcrypt_msg((inode), D_SEC, fmt, ##__VA_ARGS__) #define llcrypt_err(inode, fmt, ...) \ llcrypt_msg((inode), D_ERROR, fmt, ##__VA_ARGS__) #define LLCRYPT_MAX_IV_SIZE 32 union llcrypt_iv { struct { /* logical block number within the file */ __le64 lblk_num; /* per-file nonce; only set in DIRECT_KEY mode */ u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE]; }; u8 raw[LLCRYPT_MAX_IV_SIZE]; }; void llcrypt_generate_iv(union llcrypt_iv *iv, u64 lblk_num, const struct llcrypt_info *ci); /* fname.c */ extern int fname_encrypt(struct inode *inode, const struct qstr *iname, u8 *out, unsigned int olen); extern bool llcrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len, u32 max_len, u32 *encrypted_len_ret); /* hkdf.c */ struct llcrypt_hkdf { struct crypto_shash *hmac_tfm; }; extern int llcrypt_init_hkdf(struct llcrypt_hkdf *hkdf, const u8 *master_key, unsigned int master_key_size); /* * The list of contexts in which llcrypt uses HKDF. These values are used as * the first byte of the HKDF application-specific info string to guarantee that * info strings are never repeated between contexts. This ensures that all HKDF * outputs are unique and cryptographically isolated, i.e. knowledge of one * output doesn't reveal another. */ #define HKDF_CONTEXT_KEY_IDENTIFIER 1 #define HKDF_CONTEXT_PER_FILE_KEY 2 #define HKDF_CONTEXT_PER_MODE_KEY 3 extern int llcrypt_hkdf_expand(struct llcrypt_hkdf *hkdf, u8 context, const u8 *info, unsigned int infolen, u8 *okm, unsigned int okmlen); extern void llcrypt_destroy_hkdf(struct llcrypt_hkdf *hkdf); /* keyring.c */ /* * llcrypt_master_key_secret - secret key material of an in-use master key */ struct llcrypt_master_key_secret { /* * For v2 policy keys: HKDF context keyed by this master key. * For v1 policy keys: not set (hkdf.hmac_tfm == NULL). */ struct llcrypt_hkdf hkdf; /* Size of the raw key in bytes. Set even if ->raw isn't set. */ u32 size; /* For v1 policy keys: the raw key. Wiped for v2 policy keys. */ u8 raw[LLCRYPT_MAX_KEY_SIZE]; } __randomize_layout; /* * llcrypt_master_key - an in-use master key * * This represents a master encryption key which has been added to the * filesystem and can be used to "unlock" the encrypted files which were * encrypted with it. */ struct llcrypt_master_key { /* * The secret key material. After LL_IOC_REMOVE_ENCRYPTION_KEY is * executed, this is wiped and no new inodes can be unlocked with this * key; however, there may still be inodes in ->mk_decrypted_inodes * which could not be evicted. As long as some inodes still remain, * LL_IOC_REMOVE_ENCRYPTION_KEY can be retried, or * LL_IOC_ADD_ENCRYPTION_KEY can add the secret again. * * Locking: protected by key->sem (outer) and mk_secret_sem (inner). * The reason for two locks is that key->sem also protects modifying * mk_users, which ranks it above the semaphore for the keyring key * type, which is in turn above page faults (via keyring_read). But * sometimes filesystems call llcrypt_get_encryption_info() from within * a transaction, which ranks it below page faults. So we need a * separate lock which protects mk_secret but not also mk_users. */ struct llcrypt_master_key_secret mk_secret; struct rw_semaphore mk_secret_sem; /* * For v1 policy keys: an arbitrary key descriptor which was assigned by * userspace (->descriptor). * * For v2 policy keys: a cryptographic hash of this key (->identifier). */ struct llcrypt_key_specifier mk_spec; /* * Keyring which contains a key of type 'key_type_llcrypt_user' for each * user who has added this key. Normally each key will be added by just * one user, but it's possible that multiple users share a key, and in * that case we need to keep track of those users so that one user can't * remove the key before the others want it removed too. * * This is NULL for v1 policy keys; those can only be added by root. * * Locking: in addition to this keyrings own semaphore, this is * protected by the master key's key->sem, so we can do atomic * search+insert. It can also be searched without taking any locks, but * in that case the returned key may have already been removed. */ struct key *mk_users; /* * Length of ->mk_decrypted_inodes, plus one if mk_secret is present. * Once this goes to 0, the master key is removed from ->lsi_master_keys. * The 'struct llcrypt_master_key' will continue to live as long as the * 'struct key' whose payload it is, but we won't let this reference * count rise again. */ refcount_t mk_refcount; /* * List of inodes that were unlocked using this key. This allows the * inodes to be evicted efficiently if the key is removed. */ struct list_head mk_decrypted_inodes; spinlock_t mk_decrypted_inodes_lock; /* Per-mode tfms for DIRECT_KEY policies, allocated on-demand */ struct crypto_skcipher *mk_mode_keys[__LLCRYPT_MODE_MAX + 1]; } __randomize_layout; static inline bool is_master_key_secret_present(const struct llcrypt_master_key_secret *secret) { /* * The READ_ONCE() is only necessary for llcrypt_drop_inode() and * llcrypt_key_describe(). These run in atomic context, so they can't * take ->mk_secret_sem and thus 'secret' can change concurrently which * would be a data race. But they only need to know whether the secret * *was* present at the time of check, so READ_ONCE() suffices. */ return READ_ONCE(secret->size) != 0; } static inline const char *master_key_spec_type( const struct llcrypt_key_specifier *spec) { switch (spec->type) { case LLCRYPT_KEY_SPEC_TYPE_DESCRIPTOR: return "descriptor"; case LLCRYPT_KEY_SPEC_TYPE_IDENTIFIER: return "identifier"; } return "[unknown]"; } static inline int master_key_spec_len(const struct llcrypt_key_specifier *spec) { switch (spec->type) { case LLCRYPT_KEY_SPEC_TYPE_DESCRIPTOR: return LLCRYPT_KEY_DESCRIPTOR_SIZE; case LLCRYPT_KEY_SPEC_TYPE_IDENTIFIER: return LLCRYPT_KEY_IDENTIFIER_SIZE; } return 0; } extern struct key * llcrypt_find_master_key(struct super_block *sb, const struct llcrypt_key_specifier *mk_spec); extern int llcrypt_verify_key_added(struct super_block *sb, const u8 identifier[LLCRYPT_KEY_IDENTIFIER_SIZE]); extern int __init llcrypt_init_keyring(void); extern void __exit llcrypt_exit_keyring(void); /* keysetup.c */ struct llcrypt_mode { const char *friendly_name; const char *cipher_str; int keysize; int ivsize; bool logged_impl_name; bool needs_essiv; }; static inline bool llcrypt_mode_supports_direct_key(const struct llcrypt_mode *mode) { return mode->ivsize >= offsetofend(union llcrypt_iv, nonce); } extern struct crypto_skcipher * llcrypt_allocate_skcipher(struct llcrypt_mode *mode, const u8 *raw_key, const struct inode *inode); extern int llcrypt_set_derived_key(struct llcrypt_info *ci, const u8 *derived_key); /* keysetup_v1.c */ extern void llcrypt_put_direct_key(struct llcrypt_direct_key *dk); extern int llcrypt_setup_v1_file_key(struct llcrypt_info *ci, const u8 *raw_master_key); extern int llcrypt_setup_v1_file_key_via_subscribed_keyrings( struct llcrypt_info *ci); /* policy.c */ extern bool llcrypt_policies_equal(const union llcrypt_policy *policy1, const union llcrypt_policy *policy2); extern bool llcrypt_supported_policy(const union llcrypt_policy *policy_u, const struct inode *inode); extern int llcrypt_policy_from_context(union llcrypt_policy *policy_u, const union llcrypt_context *ctx_u, int ctx_size); #endif /* _LLCRYPT_PRIVATE_H */