linux/fs/crypto/fscrypt_private.h

/* SPDX-License-Identifier: GPL-2.0 */
/*
 * fscrypt_private.h
 *
 * Copyright (C) 2015, Google, Inc.
 *
 * Originally written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar.
 * Heavily modified since then.
 */

#ifndef _FSCRYPT_PRIVATE_H
#define _FSCRYPT_PRIVATE_H

#include <linux/fscrypt.h>
#include <linux/siphash.h>
#include <crypto/hash.h>
#include <linux/blk-crypto.h>

#define CONST_STRLEN(str)

#define FSCRYPT_FILE_NONCE_SIZE

/*
 * Minimum size of an fscrypt master key.  Note: a longer key will be required
 * if ciphers with a 256-bit security strength are used.  This is just the
 * absolute minimum, which applies when only 128-bit encryption is used.
 */
#define FSCRYPT_MIN_KEY_SIZE

#define FSCRYPT_CONTEXT_V1
#define FSCRYPT_CONTEXT_V2

/* Keep this in sync with include/uapi/linux/fscrypt.h */
#define FSCRYPT_MODE_MAX

struct fscrypt_context_v1 {};

struct fscrypt_context_v2 {};

/*
 * fscrypt_context - the encryption context of an inode
 *
 * This is the on-disk equivalent of an fscrypt_policy, stored alongside each
 * encrypted file usually in a hidden extended attribute.  It contains the
 * fields from the fscrypt_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 fscrypt itself; this is used as KDF input or as a tweak
 * to cause different files to be encrypted differently.
 */
fscrypt_context;

/*
 * Return the size expected for the given fscrypt_context based on its version
 * number, or 0 if the context version is unrecognized.
 */
static inline int fscrypt_context_size(const union fscrypt_context *ctx)
{}

/* Check whether an fscrypt_context has a recognized version number and size */
static inline bool fscrypt_context_is_valid(const union fscrypt_context *ctx,
					    int ctx_size)
{}

/* Retrieve the context's nonce, assuming the context was already validated */
static inline const u8 *fscrypt_context_nonce(const union fscrypt_context *ctx)
{}

fscrypt_policy;

/*
 * Return the size expected for the given fscrypt_policy based on its version
 * number, or 0 if the policy version is unrecognized.
 */
static inline int fscrypt_policy_size(const union fscrypt_policy *policy)
{}

/* Return the contents encryption mode of a valid encryption policy */
static inline u8
fscrypt_policy_contents_mode(const union fscrypt_policy *policy)
{}

/* Return the filenames encryption mode of a valid encryption policy */
static inline u8
fscrypt_policy_fnames_mode(const union fscrypt_policy *policy)
{}

/* Return the flags (FSCRYPT_POLICY_FLAG*) of a valid encryption policy */
static inline u8
fscrypt_policy_flags(const union fscrypt_policy *policy)
{}

static inline int
fscrypt_policy_v2_du_bits(const struct fscrypt_policy_v2 *policy,
			  const struct inode *inode)
{}

static inline int
fscrypt_policy_du_bits(const union fscrypt_policy *policy,
		       const struct inode *inode)
{}

/*
 * For encrypted symlinks, the ciphertext length is stored at the beginning
 * of the string in little-endian format.
 */
struct fscrypt_symlink_data {} __packed;

/**
 * struct fscrypt_prepared_key - a key prepared for actual encryption/decryption
 * @tfm: crypto API transform object
 * @blk_key: key for blk-crypto
 *
 * Normally only one of the fields will be non-NULL.
 */
struct fscrypt_prepared_key {};

/*
 * fscrypt_inode_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 ->i_crypt_info.  Once created, it remains until the
 * inode is evicted.
 */
struct fscrypt_inode_info {};

fscrypt_direction_t;

/* crypto.c */
extern struct kmem_cache *fscrypt_inode_info_cachep;
int fscrypt_initialize(struct super_block *sb);
int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci,
			    fscrypt_direction_t rw, u64 index,
			    struct page *src_page, struct page *dest_page,
			    unsigned int len, unsigned int offs,
			    gfp_t gfp_flags);
struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags);

void __printf(3, 4) __cold
fscrypt_msg(const struct inode *inode, const char *level, const char *fmt, ...);

#define fscrypt_warn(inode, fmt, ...)
#define fscrypt_err(inode, fmt, ...)

#define FSCRYPT_MAX_IV_SIZE

fscrypt_iv;

void fscrypt_generate_iv(union fscrypt_iv *iv, u64 index,
			 const struct fscrypt_inode_info *ci);

/*
 * Return the number of bits used by the maximum file data unit index that is
 * possible on the given filesystem, using the given log2 data unit size.
 */
static inline int
fscrypt_max_file_dun_bits(const struct super_block *sb, int du_bits)
{}

/* fname.c */
bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
				    u32 orig_len, u32 max_len,
				    u32 *encrypted_len_ret);

/* hkdf.c */
struct fscrypt_hkdf {};

int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key,
		      unsigned int master_key_size);

/*
 * The list of contexts in which fscrypt 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
#define HKDF_CONTEXT_PER_FILE_ENC_KEY
#define HKDF_CONTEXT_DIRECT_KEY
#define HKDF_CONTEXT_IV_INO_LBLK_64_KEY
#define HKDF_CONTEXT_DIRHASH_KEY
#define HKDF_CONTEXT_IV_INO_LBLK_32_KEY
#define HKDF_CONTEXT_INODE_HASH_KEY

int fscrypt_hkdf_expand(const struct fscrypt_hkdf *hkdf, u8 context,
			const u8 *info, unsigned int infolen,
			u8 *okm, unsigned int okmlen);

void fscrypt_destroy_hkdf(struct fscrypt_hkdf *hkdf);

/* inline_crypt.c */
#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci);

static inline bool
fscrypt_using_inline_encryption(const struct fscrypt_inode_info *ci)
{}

int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
				     const u8 *raw_key,
				     const struct fscrypt_inode_info *ci);

void fscrypt_destroy_inline_crypt_key(struct super_block *sb,
				      struct fscrypt_prepared_key *prep_key);

/*
 * Check whether the crypto transform or blk-crypto key has been allocated in
 * @prep_key, depending on which encryption implementation the file will use.
 */
static inline bool
fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key,
			const struct fscrypt_inode_info *ci)
{}

#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */

static inline int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci)
{
	return 0;
}

static inline bool
fscrypt_using_inline_encryption(const struct fscrypt_inode_info *ci)
{
	return false;
}

static inline int
fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
				 const u8 *raw_key,
				 const struct fscrypt_inode_info *ci)
{
	WARN_ON_ONCE(1);
	return -EOPNOTSUPP;
}

static inline void
fscrypt_destroy_inline_crypt_key(struct super_block *sb,
				 struct fscrypt_prepared_key *prep_key)
{
}

static inline bool
fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key,
			const struct fscrypt_inode_info *ci)
{
	return smp_load_acquire(&prep_key->tfm) != NULL;
}
#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */

/* keyring.c */

/*
 * fscrypt_master_key_secret - secret key material of an in-use master key
 */
struct fscrypt_master_key_secret {} __randomize_layout;

/*
 * fscrypt_master_key - an in-use master key
 *
 * This represents a master encryption key which has been added to the
 * filesystem.  There are three high-level states that a key can be in:
 *
 * FSCRYPT_KEY_STATUS_PRESENT
 *	Key is fully usable; it can be used to unlock inodes that are encrypted
 *	with it (this includes being able to create new inodes).  ->mk_present
 *	indicates whether the key is in this state.  ->mk_secret exists, the key
 *	is in the keyring, and ->mk_active_refs > 0 due to ->mk_present.
 *
 * FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED
 *	Removal of this key has been initiated, but some inodes that were
 *	unlocked with it are still in-use.  Like ABSENT, ->mk_secret is wiped,
 *	and the key can no longer be used to unlock inodes.  Unlike ABSENT, the
 *	key is still in the keyring; ->mk_decrypted_inodes is nonempty; and
 *	->mk_active_refs > 0, being equal to the size of ->mk_decrypted_inodes.
 *
 *	This state transitions to ABSENT if ->mk_decrypted_inodes becomes empty,
 *	or to PRESENT if FS_IOC_ADD_ENCRYPTION_KEY is called again for this key.
 *
 * FSCRYPT_KEY_STATUS_ABSENT
 *	Key is fully removed.  The key is no longer in the keyring,
 *	->mk_decrypted_inodes is empty, ->mk_active_refs == 0, ->mk_secret is
 *	wiped, and the key can no longer be used to unlock inodes.
 */
struct fscrypt_master_key {} __randomize_layout;

static inline const char *master_key_spec_type(
				const struct fscrypt_key_specifier *spec)
{}

static inline int master_key_spec_len(const struct fscrypt_key_specifier *spec)
{}

void fscrypt_put_master_key(struct fscrypt_master_key *mk);

void fscrypt_put_master_key_activeref(struct super_block *sb,
				      struct fscrypt_master_key *mk);

struct fscrypt_master_key *
fscrypt_find_master_key(struct super_block *sb,
			const struct fscrypt_key_specifier *mk_spec);

int fscrypt_get_test_dummy_key_identifier(
			  u8 key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]);

int fscrypt_add_test_dummy_key(struct super_block *sb,
			       struct fscrypt_key_specifier *key_spec);

int fscrypt_verify_key_added(struct super_block *sb,
			     const u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]);

int __init fscrypt_init_keyring(void);

/* keysetup.c */

struct fscrypt_mode {};

extern struct fscrypt_mode fscrypt_modes[];

int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key,
			const u8 *raw_key, const struct fscrypt_inode_info *ci);

void fscrypt_destroy_prepared_key(struct super_block *sb,
				  struct fscrypt_prepared_key *prep_key);

int fscrypt_set_per_file_enc_key(struct fscrypt_inode_info *ci,
				 const u8 *raw_key);

int fscrypt_derive_dirhash_key(struct fscrypt_inode_info *ci,
			       const struct fscrypt_master_key *mk);

void fscrypt_hash_inode_number(struct fscrypt_inode_info *ci,
			       const struct fscrypt_master_key *mk);

int fscrypt_get_encryption_info(struct inode *inode, bool allow_unsupported);

/**
 * fscrypt_require_key() - require an inode's encryption key
 * @inode: the inode we need the key for
 *
 * If the inode is encrypted, set up its encryption key if not already done.
 * Then require that the key be present and return -ENOKEY otherwise.
 *
 * No locks are needed, and the key will live as long as the struct inode --- so
 * it won't go away from under you.
 *
 * Return: 0 on success, -ENOKEY if the key is missing, or another -errno code
 * if a problem occurred while setting up the encryption key.
 */
static inline int fscrypt_require_key(struct inode *inode)
{}

/* keysetup_v1.c */

void fscrypt_put_direct_key(struct fscrypt_direct_key *dk);

int fscrypt_setup_v1_file_key(struct fscrypt_inode_info *ci,
			      const u8 *raw_master_key);

int fscrypt_setup_v1_file_key_via_subscribed_keyrings(
				struct fscrypt_inode_info *ci);

/* policy.c */

bool fscrypt_policies_equal(const union fscrypt_policy *policy1,
			    const union fscrypt_policy *policy2);
int fscrypt_policy_to_key_spec(const union fscrypt_policy *policy,
			       struct fscrypt_key_specifier *key_spec);
const union fscrypt_policy *fscrypt_get_dummy_policy(struct super_block *sb);
bool fscrypt_supported_policy(const union fscrypt_policy *policy_u,
			      const struct inode *inode);
int fscrypt_policy_from_context(union fscrypt_policy *policy_u,
				const union fscrypt_context *ctx_u,
				int ctx_size);
const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir);

#endif /* _FSCRYPT_PRIVATE_H */