// guide
Encryption & LUKS
Password-protected boot files on the ESP, and one password for the whole boot.
The two layers
VISORENC protects the boot files sitting on the (always unencrypted) ESP: kernels, UKIs, and initrds are stored as encrypted, authenticated containers and decrypted in memory after you type a password in the menu. LUKS protects your root filesystem; Visor never parses LUKS itself — it hands your initramfs what it needs to unlock the disk. The two compose, and one password can drive both.
One-command setup
sudo visor encrypt /boot/vmlinuz-linux /boot/initramfs-linux.img --title "Encrypted Arch"
This single command:
- prompts for one password and encrypts both files with it,
- copies the containers to
\EFI\visor\, - generates a finished boot entry using your current kernel cmdline (from
/proc/cmdline), - detects a LUKS root (
cryptdevice=/rd.luks.*on the cmdline) and addsluks = 1with the rightluks_preset(mkinitcpio or dracut, detected from your installed initramfs tooling), - offers to append the entry to
boot.conffor you, and - prints the exact
cryptsetup luksAddKeycommand to enroll that same password on your LUKS device.
Flags: --title TEXT (menu name), --no-luks,
--no-config (print the entry only), --out PATH /
--esp PATH, --name FILE, --iterations N,
--initrd (the single input is an initrd).
What boot looks like
power on ─▶ Visor menu ─▶ one password prompt
│
├─ decrypts kernel + initrd containers in RAM (authenticated first)
├─ injects the password as a keyfile into the decrypted initrd (cpio append)
├─ adds cryptkey=rootfs:… / rd.luks.key=… to the cmdline
▼
kernel boots ─▶ initramfs unlocks LUKS root from the keyfile ─▶ desktop
One password, one prompt. The prerequisite: that password must also be a valid LUKS passphrase — enroll it once with
sudo cryptsetup luksAddKey <device> (the keyfile Visor injects
contains the exact password bytes, no trailing newline, so a normal passphrase
slot matches).
At the prompt, F2 toggles showing what you typed — useful to confirm your keyboard layout before submitting. If luks_confirm=1, the password is asked for twice and a mismatch reprompts instead of booting with a typo. If luks_verbose=1, quiet and splash are stripped from the cmdline so the initramfs retry prompt stays visible when the passphrase is rejected.
Entry keys
| Key | Meaning |
|---|---|
encrypted = 1 | Both kernel and initrd are VISORENC containers. |
kernel_encrypted = 1 / initrd_encrypted = 1 | Only one of the two is encrypted. |
luks = 1 | Inject the entered password as a temporary keyfile into the in-memory initrd. |
luks_preset | mkinitcpio/arch → adds cryptkey=rootfs:<path> · dracut/systemd → adds rd.luks.key=<path>. |
luks_key_path | Keyfile path created inside the initramfs. Default /crypto_keyfile.bin. |
luks_cmdline | Manual kernel options for the keyfile; overrides the preset. |
luks_confirm | 1 = ask for the passphrase twice at the prompt; a mismatch reprompts instead of booting with a typo. |
luks_verbose | 1 = remove quiet and splash from this entry's cmdline so the initramfs retry prompt is visible when a passphrase is rejected. |
A single menu prompt covers encrypted, initrd_encrypted, and
luks together — the same captured password decrypts the containers and
becomes the keyfile.
Mapper-name consistency
If you are writing LUKS entries by hand, the mapper device name in your kernel
cmdline must match what /etc/fstab and /etc/crypttab expect. Use
rd.luks.name=<UUID>=<name> (not rd.luks.uuid= alone) so the name
matches root=/dev/mapper/<name> and every fstab mount. See the full
mapper-name consistency checklist
in the configuration reference.
The VISORENC container format (v2)
| Field | Size | Notes |
|---|---|---|
| Magic | 8 | VISORENC |
| Version | 4 | 2 |
| Iterations | 4 | PBKDF2-HMAC-SHA256 work factor (default 600,000; max 5,000,000) |
| Plain length | 8 | Original file size |
| Salt | 16 | Random per file |
| Nonce | 12 | Random per file |
| HMAC tag | 32 | HMAC-SHA256 over header + ciphertext |
| Ciphertext | n | ChaCha20 stream |
Key derivation: PBKDF2-HMAC-SHA256 → 64 bytes (32 for ChaCha20, 32 for the HMAC). The tag is verified before decryption, so a modified container is refused, not booted. Passwords are ASCII, up to 510 characters (the menu's input limit). Decrypted buffers and captured passwords are wiped from memory after use.
Threat model, honestly
- An attacker holding your powered-off disk sees opaque authenticated blobs on the ESP and a LUKS-encrypted root. They cannot read or undetectably modify the kernel/initrd containers.
- The keyfile handoff means your disk passphrase transits the initrd in RAM — the same trust level as typing it into the initramfs prompt.
- This is not full-disk-encryption parsing in the bootloader, and it does not replace Secure Boot — see Secure Boot for what protects the boot chain itself.
- Rebuilding your initramfs means re-running
visor encrypt: the container is a snapshot of the file.