fs/crypto/fname.c
Source file repositories/reference/linux-study-clean/fs/crypto/fname.c
File Facts
- System
- Linux kernel
- Corpus path
fs/crypto/fname.c- Extension
.c- Size
- 18005 bytes
- Lines
- 515
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
crypto/sha2.hcrypto/skcipher.hlinux/export.hlinux/namei.hlinux/scatterlist.hlinux/base64.hfscrypt_private.h
Detected Declarations
struct fscrypt_nokey_namefunction fscrypt_fname_encryptfunction fname_decryptfunction __fscrypt_fname_encrypted_sizefunction fscrypt_fname_encrypted_sizefunction fscrypt_fname_alloc_bufferfunction fscrypt_fname_free_bufferfunction fscrypt_fname_disk_to_usrfunction fscrypt_setup_filenamefunction fscrypt_match_namefunction fscrypt_fname_siphashfunction fscrypt_d_revalidateexport fscrypt_fname_encryptexport fscrypt_fname_encrypted_sizeexport fscrypt_fname_alloc_bufferexport fscrypt_fname_free_bufferexport fscrypt_fname_disk_to_usrexport fscrypt_setup_filenameexport fscrypt_match_nameexport fscrypt_fname_siphashexport fscrypt_d_revalidate
Annotated Snippet
struct fscrypt_nokey_name {
u32 dirhash[2];
u8 bytes[149];
u8 sha256[SHA256_DIGEST_SIZE];
}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */
/*
* Decoded size of max-size no-key name, i.e. a name that was abbreviated using
* the strong hash and thus includes the 'sha256' field. This isn't simply
* sizeof(struct fscrypt_nokey_name), as the padding at the end isn't included.
*/
#define FSCRYPT_NOKEY_NAME_MAX offsetofend(struct fscrypt_nokey_name, sha256)
/* Encoded size of max-size no-key name */
#define FSCRYPT_NOKEY_NAME_MAX_ENCODED \
BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX)
static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
{
return name_is_dot_dotdot(str->name, str->len);
}
/**
* fscrypt_fname_encrypt() - encrypt a filename
* @inode: inode of the parent directory (for regular filenames)
* or of the symlink (for symlink targets). Key must already be
* set up.
* @iname: the filename to encrypt
* @out: (output) the encrypted filename
* @olen: size of the encrypted filename. It must be at least @iname->len.
* Any extra space is filled with NUL padding before encryption.
*
* Return: 0 on success, -errno on failure
*/
int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
u8 *out, unsigned int olen)
{
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
union fscrypt_iv iv;
struct scatterlist sg;
int err;
/*
* Copy the filename to the output buffer for encrypting in-place and
* pad it with the needed number of NUL bytes.
*/
if (WARN_ON_ONCE(olen < iname->len))
return -ENOBUFS;
memcpy(out, iname->name, iname->len);
memset(out + iname->len, 0, olen - iname->len);
fscrypt_generate_iv(&iv, 0, ci);
skcipher_request_set_callback(
req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
NULL, NULL);
sg_init_one(&sg, out, olen);
skcipher_request_set_crypt(req, &sg, &sg, olen, &iv);
err = crypto_skcipher_encrypt(req);
if (err)
fscrypt_err(inode, "Filename encryption failed: %d", err);
return err;
}
EXPORT_SYMBOL_GPL(fscrypt_fname_encrypt);
/**
* fname_decrypt() - decrypt a filename
* @inode: inode of the parent directory (for regular filenames)
* or of the symlink (for symlink targets)
* @iname: the encrypted filename to decrypt
* @oname: (output) the decrypted filename. The caller must have allocated
* enough space for this, e.g. using fscrypt_fname_alloc_buffer().
*
* Return: 0 on success, -errno on failure
*/
static int fname_decrypt(const struct inode *inode,
const struct fscrypt_str *iname,
struct fscrypt_str *oname)
{
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
union fscrypt_iv iv;
struct scatterlist src_sg, dst_sg;
int err;
fscrypt_generate_iv(&iv, 0, ci);
Annotation
- Immediate include surface: `crypto/sha2.h`, `crypto/skcipher.h`, `linux/export.h`, `linux/namei.h`, `linux/scatterlist.h`, `linux/base64.h`, `fscrypt_private.h`.
- Detected declarations: `struct fscrypt_nokey_name`, `function fscrypt_fname_encrypt`, `function fname_decrypt`, `function __fscrypt_fname_encrypted_size`, `function fscrypt_fname_encrypted_size`, `function fscrypt_fname_alloc_buffer`, `function fscrypt_fname_free_buffer`, `function fscrypt_fname_disk_to_usr`, `function fscrypt_setup_filename`, `function fscrypt_match_name`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.