GUIDE · PREVIEW
GUIDE / CON.25
source: docs/guide/concepts/LUKS.md
Concepts

LUKS

What It Is

LUKS (Linux Unified Key Setup) is the standard for disk encryption on Linux. It provides a consistent on-disk format for encrypted partitions, supporting multiple keyslots, key management, and metadata storage. LUKS sits on top of dm-crypt (the kernel's encryption layer) and adds the user-facing key management.

If dm-crypt is the engine that encrypts and decrypts data, LUKS is the ignition system that manages the keys to start it.

Why It Matters

Without LUKS, you'd need to manage encryption keys manually: decide on a cipher, generate a key, figure out where to store the key metadata, handle key rotation, support multiple unlock methods. LUKS standardizes all of this into a well-tested format with tooling (cryptsetup).

LUKS also enables the keyslot model: one encrypted partition can be unlocked by multiple different credentials (password, key file, YubiKey, TPM), each stored in its own keyslot. All keyslots protect the same master key -- adding or removing a keyslot never re-encrypts the data.

How It Works

LUKS2 On-Disk Format

A LUKS2 partition starts with a header (typically 16 MB) followed by the encrypted data:

+------------------+------------------------------------------+
|   LUKS2 Header   |         Encrypted Data (AES-256-XTS)     |
|                  |                                          |
| - JSON metadata  |    dm-crypt handles read/write here      |
| - Keyslot area   |                                          |
| - Salt, cipher   |                                          |
+------------------+------------------------------------------+

JSON metadata: LUKS2 replaced LUKS1's binary header with JSON, making it more flexible and extensible. The metadata describes the cipher, key size, PBKDF parameters, and keyslot layout.

Keyslot area: Up to 32 keyslots (LUKS2; LUKS1 had 8). Each keyslot holds an independently encrypted copy of the master key. The master key is what actually encrypts the data. Keyslots are just different ways to recover it.

Master Key and Keyslots

The critical design: the data is encrypted with a randomly generated master key. This master key is never stored in plaintext. Instead, each keyslot encrypts a copy of the master key with a different credential:

Keyslot 0: master_key encrypted with PBKDF2(password)
Keyslot 1: master_key encrypted with key_file_contents
Keyslot 2: master_key encrypted with yubikey_hmac_response

To unlock the partition, you provide any one credential. cryptsetup tries it against each keyslot until one succeeds, then uses the recovered master key to set up dm-crypt.

This means:

  • Changing a password doesn't re-encrypt the disk (just replaces a keyslot)
  • Adding a recovery key doesn't affect existing keyslots
  • Removing a compromised credential only removes its keyslot

Common Operations

# Create a LUKS2 partition
cryptsetup luksFormat /dev/vdb

# Open (unlock) the partition
cryptsetup luksOpen /dev/vdb persist

# The decrypted device appears as /dev/mapper/persist
mkfs.ext4 /dev/mapper/persist
mount /dev/mapper/persist /persist

# Add a keyslot (e.g., a key file for automated unlock)
cryptsetup luksAddKey /dev/vdb /path/to/keyfile

# Remove a keyslot
cryptsetup luksKillSlot /dev/vdb 1

# Close (lock) the partition
cryptsetup luksClose persist

LUKS1 vs LUKS2

Feature LUKS1 LUKS2
Header format Binary JSON
Max keyslots 8 32
PBKDF PBKDF2 only Argon2id (default), PBKDF2
Integrity None Optional dm-integrity
Online reencryption No Yes
Token support No Yes (systemd-cryptenroll, FIDO2, TPM2)

LUKS2 is the default since cryptsetup 2.1 (2019). FortrOS uses LUKS2.

How FortrOS Uses It

Encrypted /persist: Each node's /persist partition is LUKS2-encrypted. The master key is protected by:

  • Keyslot 0: Org-derived key (HKDF from preboot_secret + ca_pubkey + generation_id). Used on every normal boot.
  • Keyslots 1-N: Admin YubiKey keyslots for disaster recovery.

Rolling upgrades: When upgrading to a new generation, the LUKS key changes (generation_id changes). prepare-upgrade adds a new keyslot for the new generation's key. After successful boot, cleanup-upgrade removes the old keyslot. See 10 Sustaining the Org.

Revocation: Deleting a generation_secret from the generation authority makes it impossible to derive the LUKS key for that generation. Machines with that generation can't unlock /persist. This is cryptographic enforcement of "cold boot prevents stolen devices."

First boot: cryptsetup luksFormat creates /persist with the initial keyslot. Subsequent boots use cryptsetup luksOpen.

Failed unlock: If luksOpen fails (generation revoked, /persist corrupted), the preboot reformats from scratch. Identity and cache are lost, but the machine can re-enroll.

Alternatives

dm-crypt without LUKS: Raw dm-crypt with a plain key. No keyslot management, no metadata, no standard format. Suitable only for ephemeral encrypted volumes where key management isn't needed.

eCryptfs / fscrypt: File-level encryption (individual files/directories encrypted, not the whole partition). More granular but more complex. Android uses fscrypt for per-user encryption. FortrOS encrypts the whole /persist partition -- file-level granularity isn't needed.

BitLocker (Windows): Proprietary, Windows-only. Similar keyslot concept (TPM, PIN, recovery key) but closed-source format.

ZFS native encryption: Built into the ZFS filesystem. Encrypts datasets (logical filesystems). FortrOS doesn't use ZFS.

Links