Crypto API and Storage Encryption
On this page
Changing the unlock passphrase usually does not require rewriting the entire disk, but changing the volume key may require re-encryption. Cryptographic primitives, key management, and the actual data path need to be understood in layers.
Protecting offline media and preventing malicious processes from reading files on an unlocked system are different goals; storage encryption still needs to be combined with access control.
| Goal | Reference |
|---|---|
| Algorithm instances and asynchronous requests | Section 1 |
| Block encryption, keyslots, and directory policies | Sections 2–3 |
| Network encryption, TPM, and digest experiments | Sections 4–6 |
1. Crypto API: Algorithm Instances and Single Requests
| Interface Category | Task | Example |
|---|---|---|
| skcipher | Symmetric encryption/decryption | XTS, CBC, etc. |
| AEAD | Encrypt and authenticate data and associated data | GCM, ChaCha20-Poly1305 |
| shash / ahash | Synchronous/asynchronous digest or keyed hash | SHA-256, HMAC |
| akcipher | Asymmetric encryption interfaces | RSA operations |
| kpp | Key agreement | DH, ECDH |
| rng | Specific random number generator interface | Registered RNG implementations |
ECDH should be categorized under key agreement and should not be used as an example of an RSA-style encryption interface. Common kernel random byte requirements often use the random number subsystem interfaces such as get_random_bytes(), and not every caller allocates a crypto_rng themselves.
tfm is a transformation object that configures algorithm and key information; an operation usually also requires a request, source/destination scatterlist, length, and IV. The correct skcipher encryption entry point accepts skcipher_request *, not a fake crypto_skcipher_encrypt(tfm, src, dst, len).
- Allocate tfm, check for errors, and set the key.
- Establish request, callback, source/destination ranges, and IV.
- Submit and distinguish between synchronous completion or asynchronous processing based on the return status.
- Only after satisfying the completion contract, release the request, data, and context.
In sleepable contexts, you can use crypto_wait_req() to wait as per official examples; do not move it into atomic contexts. See skcipher API and complete example.
Algorithm Names Are Not Concrete Execution Units
Names like xts(aes) combine templates and underlying algorithms. Multiple implementations can provide the same generic algorithm name; the Crypto API selects based on matching conditions, implementation priority, etc.; specifying a driver name narrows the selection. /proc/crypto can observe currently registered implementations, but it is not a complete list of all possible algorithm combinations that can be loaded on the system.
AES-NI, ARM encryption extensions, and independent accelerators have different invocation costs. Small data blocks, queue latency, DMA, and copy costs can all affect results; you cannot guarantee that "the existence of a hardware implementation makes it fixedly ten times faster." The kernel also has direct cryptographic library interfaces, and not every cryptographic operation must go through dynamic tfm allocation. See Crypto API Architecture.
2. Where dm-crypt and LUKS Operate at Different Layers
dm-crypt is a block encryption target for device-mapper, handling read/write data sent to the mapped device; the filesystem above usually sees decrypted blocks. LUKS is a disk format and key management convention, read by user-space tools like cryptsetup to parse the header, complete the unlock, and then configure the kernel mapping. The kernel dm-crypt does not parse each LUKS JSON keyslot.
| Change | Layer Typically Involved |
|---|---|
| Add or change passphrase | PBKDF derives unlock material, handles keyslot |
| Restore volume key and open mapping | Uses key material protected in the keyslot |
| Actually change volume key | Involves data re-encryption process |
Therefore, changing the passphrase is usually not equivalent to re-encrypting the entire filesystem; the costs and recovery requirements for the two operations are different.
LUKS1 has a maximum of 8 keyslots; LUKS2 supports up to 32 slots, with the actual available number also limited by conditions such as keyslot area size. LUKS2 has redundant metadata and JSON descriptions, with clear layouts and configurable parameters for the header, keyslot area, and data offset; you cannot uniformly call them a "fixed first 16 MB header." See LUKS2 Format Specification and cryptsetup parameters.
The availability and parameters of PBKDF2, Argon2i, and Argon2id depend on the format and tool configuration. Memory cost can increase the cost of offline passphrase guessing, but it cannot make weak passphrases into unbreakable keys. Do not confuse the PBKDF overhead during the unlock phase with the encryption overhead for each sector read/write.
Confidentiality Does Not Equal Integrity
Common XTS mode provides sector data confidentiality but does not provide universal tamper authentication and anti-rollback guarantees. When authentication encryption or integrity protection is needed, you must choose the corresponding mode, metadata storage, and cooperating mechanisms such as dm-integrity, and understand their boundaries.
Allowing discard can expose usage space pattern information. When unlocked, processes with read privileges can still obtain plaintext; volume keys and cached plaintext also participate in the memory threat model of the running system. See dm-crypt documentation.
Below, we actually encrypt the same public example content in the browser, then flip one bit in the ciphertext. Compare unauthenticated CTR with authenticated GCM: being able to decrypt some bytes, and those bytes passing verification, are two different results.
Unauthenticated CTR can decrypt modified plaintext after a ciphertext bit flip; GCM verifies the authentication tag and rejects the modification here. Confidentiality, integrity, and anti-rollback need to be explained separately.
3. fscrypt: Choosing Protection Scope Within the Filesystem
fscrypt provides file content and filename encryption for supported filesystems. Directory policies allow different directory trees to use different master keys, facilitating the management of multiple unlock domains within the same filesystem.
It usually does not hide non-filename metadata such as file size, permissions, timestamps, and directory structure, nor can it guarantee that offline observers cannot correlate files. The default per-file derivation and nonce mechanisms have policy differences such as DIRECT_KEY and IV_INO_LBLK; you cannot generalize it as "every file has an independent data key under any configuration."
Standard fscrypt design mainly protects static data confidentiality and does not automatically provide complete filesystem authentication against active tampering and rollback. Removing the master key also needs to consider derived keys still in use in open files and caches; you cannot interpret the ioctl return as all plaintext disappearing instantly.
New directory policies are usually set when conditions such as an empty directory are met, and subsequently created files inherit the corresponding policy; it does not magically convert an existing plaintext directory. FS_IOC_GET_ENCRYPTION_PWSALT is a historical passphrase derivation auxiliary interface, not a general interface for reading unique salt values for any directory. Policies and limitations are documented in fscrypt documentation.
| Comparison Point | dm-crypt | fscrypt |
|---|---|---|
| Management Boundary | Block mapping | Policies and key domains within the filesystem |
| Filesystem Metadata | Becomes encrypted blocks together when inside the encryption mapping | Many non-filename metadata remain visible |
| Unlock Granularity | Usually the entire mapping | Can manage keys for different directory trees |
| Access Control After Unlock | Still relies on permissions/LSM, etc. | Still relies on permissions/LSM, etc. |
The two can also be stacked; they are not mutually exclusive product replacements.
4. WireGuard and kTLS: Encryption at Different Network Layers
WireGuard provides Layer 3 encrypted tunnels, using fixed protocol components such as Noise handshake, Curve25519, and ChaCha20-Poly1305. Static public keys identify peers, and the handshake generates session keys; packet counters, authentication, and replay protection jointly participate in protection. Key updates are triggered by conditions such as time, message count, and session state, not strictly executed as a timed action every two minutes unconditionally.
Curve25519 is not a post-quantum algorithm. WireGuard can mix in pre-shared symmetric keys as additional protection, but this cannot be generalized as "post-quantum issues are unimportant" or the entire system has obtained all post-quantum security attributes. The configuration interface mainly uses generic netlink, and network device creation also involves standard network interface management. See WireGuard Protocol.
kTLS passes supported TLS record layer send/receive processing to the kernel or hardware; handshake, certificate verification, and protocol state management are still mainly handled by user-space TLS libraries. After connection negotiation, TCP TLS ULP needs to be set, and cipher states required for TX/RX configured separately; you cannot just copy a setsockopt and consider it a complete TLS client.
Paths such as sendfile can reduce user-space copying, but software encryption, NIC offload, and zero-copy sending are different capabilities; whether they are available depends on kernel, protocol, algorithm, and driver support. See kTLS documentation.
5. TPM: Use Secrets According to Policy, and Manage the Policy Itself
TPM can protect key objects and constrain unsealing or usage based on conditions such as PCR. Typical LUKS integration generates unlock material, associates it with TPM objects/policies and LUKS tokens; this does not mean keeping the entire disk encryption key permanently only inside the TPM for every sector encryption.
PCR is the accumulated result of measuring events, not the TPM understanding "this kernel is definitely benign." Which PCRs are selected, whether the measurement chain is trusted, and who signs the authorization policy determine the unlock constraints. Allowing legitimate upgrades also requires policy updates, signed PCR policies, or recovery credentials design.
What Do Boot Authorization, Measurement, and Unsealing Prove Respectively?
Secure Boot verifies the authorization relationship of boot code, measured boot records measurements, and TPM sealing restricts secret usage based on policies; the three can cooperate but cannot replace each other. Runtime vulnerabilities after normal unlock are not automatically prevented by PCR binding. Implementations can refer to systemd-cryptenroll source code and documentation.
6. Observing a Digest Request Using AF_ALG
Below, we use the Linux AF_ALG call to the kernel SHA-256 to perform a known result check on a public string, without reading keys or modifying storage. Requires Python/Linux support for AF_ALG, and the kernel has enabled the corresponding algorithm user interface. It demonstrates kernel interfaces and does not imply that general applications should replace their own cryptographic libraries.
=
, =
=
=
assert == 32 and ==
When AF_ALG is not enabled in this environment, creating a socket will return EAFNOSUPPORT; this indicates that the interface capability is unavailable, and you cannot judge that the SHA-256 algorithm itself is erroneous based on this.
If socket creation returns EAFNOSUPPORT, first check support for CONFIG_CRYPTO_USER_API_HASH, etc.; you cannot judge that the SHA-256 algorithm implementation is erroneous because of this.
Digest matching proves that this call path yields the expected result, but does not prove that the entire encrypted storage configuration, key management, or hardware offload is correct. See Kernel Userspace Crypto Interface for AF_ALG interface limitations and support status.