security/integrity/evm/evm_crypto.c
Source file repositories/reference/linux-study-clean/security/integrity/evm/evm_crypto.c
File Facts
- System
- Linux kernel
- Corpus path
security/integrity/evm/evm_crypto.c- Extension
.c- Size
- 11924 bytes
- Lines
- 460
- Domain
- Core OS
- Bucket
- Security And Isolation
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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
linux/export.hlinux/hex.hlinux/crypto.hlinux/xattr.hlinux/evm.hkeys/encrypted-type.hcrypto/hash.hcrypto/hash_info.hevm.h
Detected Declarations
struct h_miscfunction evm_set_keyfunction hmac_add_miscfunction dump_security_xattr_lfunction dump_security_xattrfunction evm_calc_hmac_or_hashfunction evm_calc_hmacfunction evm_calc_hashfunction evm_is_immutablefunction evm_update_evmxattrfunction evm_init_hmacfunction list_for_each_entry_locklessfunction evm_init_keyexport evm_set_key
Annotated Snippet
struct h_misc {
/*
* Although inode->i_ino is now u64, this field remains
* unsigned long to allow existing HMAC and signatures from
* 32-bit hosts to continue working when i_ino hasn't changed
* and fits in a u32.
*/
unsigned long ino;
__u32 generation;
uid_t uid;
gid_t gid;
umode_t mode;
} hmac_misc;
memset(&hmac_misc, 0, sizeof(hmac_misc));
/* Don't include the inode or generation number in portable
* signatures
*/
if (type != EVM_XATTR_PORTABLE_DIGSIG) {
hmac_misc.ino = inode->i_ino;
hmac_misc.generation = inode->i_generation;
}
/* The hmac uid and gid must be encoded in the initial user
* namespace (not the filesystems user namespace) as encoding
* them in the filesystems user namespace allows an attack
* where first they are written in an unprivileged fuse mount
* of a filesystem and then the system is tricked to mount the
* filesystem for real on next boot and trust it because
* everything is signed.
*/
hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
hmac_misc.mode = inode->i_mode;
crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
if ((evm_hmac_attrs & EVM_ATTR_FSUUID) &&
type != EVM_XATTR_PORTABLE_DIGSIG)
crypto_shash_update(desc, (u8 *)&inode->i_sb->s_uuid, UUID_SIZE);
crypto_shash_final(desc, digest);
pr_debug("hmac_misc: (%zu) [%*phN]\n", sizeof(struct h_misc),
(int)sizeof(struct h_misc), &hmac_misc);
}
/*
* Dump large security xattr values as a continuous ascii hexadecimal string.
* (pr_debug is limited to 64 bytes.)
*/
static void dump_security_xattr_l(const char *prefix, const void *src,
size_t count)
{
#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
char *asciihex, *p;
p = asciihex = kmalloc(count * 2 + 1, GFP_KERNEL);
if (!asciihex)
return;
p = bin2hex(p, src, count);
*p = 0;
pr_debug("%s: (%zu) %.*s\n", prefix, count, (int)count * 2, asciihex);
kfree(asciihex);
#endif
}
static void dump_security_xattr(const char *name, const char *value,
size_t value_len)
{
if (value_len < 64)
pr_debug("%s: (%zu) [%*phN]\n", name, value_len,
(int)value_len, value);
else
dump_security_xattr_l(name, value, value_len);
}
/*
* Calculate the HMAC value across the set of protected security xattrs.
*
* Instead of retrieving the requested xattr, for performance, calculate
* the hmac using the requested xattr value. Don't alloc/free memory for
* each xattr, but attempt to re-use the previously allocated memory.
*/
static int evm_calc_hmac_or_hash(struct dentry *dentry,
const char *req_xattr_name,
const char *req_xattr_value,
size_t req_xattr_value_len,
uint8_t type, struct evm_digest *data,
struct evm_iint_cache *iint)
{
struct inode *inode = d_inode(d_real(dentry, D_REAL_METADATA));
struct xattr_list *xattr;
Annotation
- Immediate include surface: `linux/export.h`, `linux/hex.h`, `linux/crypto.h`, `linux/xattr.h`, `linux/evm.h`, `keys/encrypted-type.h`, `crypto/hash.h`, `crypto/hash_info.h`.
- Detected declarations: `struct h_misc`, `function evm_set_key`, `function hmac_add_misc`, `function dump_security_xattr_l`, `function dump_security_xattr`, `function evm_calc_hmac_or_hash`, `function evm_calc_hmac`, `function evm_calc_hash`, `function evm_is_immutable`, `function evm_update_evmxattr`.
- Atlas domain: Core OS / Security And Isolation.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.