Using 4096-Byte Sectors with LUKS2 on 4096/512e Storage Devices
Encryption Sector Alignment and Performance on Advanced Format Drives
LUKS Overview
LUKS (Linux Unified Key Setup) is the standard for disk encryption on Linux, first released in 2004. It stores all encryption metadata in a volume header, making LUKS volumes highly portable across GNU/Linux distributions. The header supports multiple key slots, each containing the same master key encrypted with a different passphrase or key material. This allows you to add, remove, or change passphrases without re-encrypting the entire volume.
LUKS is built on Linux’s Device Mapper subsystem — specifically the dm-crypt encryption target — and can be combined with other targets such as LVM. The main userspace tool is cryptsetup, which provides commands like luksFormat, luksOpen, luksClose, luksAddKey, and luksRemoveKey.
Common use cases:
- Full disk encryption during OS installation
- Encrypting external USB drives and SSDs
- Protecting sensitive data in virtual machines and containers
4096/512e Storage Devices
Most modern hard drives and many SSDs are 4096/512e devices (Advanced Format with 512-byte emulation). They use 4096-byte physical sectors internally (called large sectors), while presenting a 512-byte logical sector interface for compatibility. These drives guarantee atomic read/write operations at the 4096-byte physical sector level.
Advantages of 4096-Byte Sectors in LUKS
LUKS primarily uses the XTS encryption mode. XTS requires two keys and uses a tweak derived from the sector number:
x = E(k2, i) × α^j c = E(k1, (p ⊕ x)) ⊕ x
α is a primitive element in the finite field GF(2¹²⁸) (or GF(2²⁵⁶) for 256-bit blocks), and j is the block offset within the sector.
A single large (4096-byte) sector contains eight small (512-byte) sectors. When the filesystem block size matches the large sector size and is properly aligned:
- Encrypting at 512-byte granularity requires 8 separate
E(k2, i)operations per filesystem block. - Encrypting at 4096-byte granularity requires only 1
E(k2, i)operation; the remaining 7 tweaks are generated by simple multiplication by powers ofα.
This significantly improves performance, especially on storage devices that are physically 4K-native. Note that dm-crypt sector size only affects how plaintext filesystem blocks are transformed into ciphertext. When properly aligned, the resulting encrypted data is still written as complete 4096-byte physical sectors (or eight contiguous aligned 512-byte sectors).
Important: Using 4096-byte encryption sectors on devices that do not guarantee atomic 4K writes can increase the risk of data corruption in case of power loss or crashes.
Creating or Converting to a LUKS2 Volume with 4096-Byte Sectors
On recent versions of cryptsetup, LUKS2 volumes created on properly aligned partitions (where both the partition size and offset are multiples of 4096 bytes) on 4K-native drives will automatically use a 4096-byte sector size.
To convert an existing LUKS2 volume that is currently using 512-byte sectors, use:
cryptsetup reencrypt --sector-size 4096 <device>
By default, reencrypt generates a new master key. If the LUKS2 header contains multiple key slots, cryptsetup will prompt for the passphrase of every existing slot. You can avoid this by adding the –keep-key option to keep the existing master key. In that case, unlocking just one key slot is sufficient to start the re-encryption process.
During re-encryption, cryptsetup continuously updates the LUKS2 header. It reads batches of sectors from the device into memory, decrypts them, re-encrypts them with the new parameters, and writes them back. To support this, four area descriptors are maintained in the LUKS2 header:
- Converted area — uses the new (“future”) encryption parameters
- To-be-converted area — still uses the old (“original”) parameters
- Original descriptor and Future descriptor — both describe the full volume but are only used for reference
The original and future descriptors cover the entire volume but are inactive during conversion. The boundary between the converted and to-be-converted areas moves forward as the process progresses. The conversion can be interrupted and resumed at any time, and a partially converted volume remains fully accessible even while the process is ongoing.
GPT: A Hidden Obstacle to Using 4096-Byte Sectors with LUKS2
The total capacity of a physically 4K-native drive is always a multiple of 4096 bytes, and partitions are usually well-aligned at both ends. However, GPT partitioning introduces a subtle issue:
A default GPT table supporting 128 partition entries occupies 33 sectors (1 header + 32 entry sectors) at both the beginning and the end of the disk. When the last partition occupies all remaining space, its size in 512-byte sectors is often not a multiple of 8 — typically leaving a remainder of 7 (assuming the partition starts on a properly aligned boundary). Because the size is not a multiple of 4096 bytes, cryptsetup will refuse to create or convert the volume to 4096-byte sectors.
In order to resolve this issue, one can either shrink this last partition by 7 512-byte sectors, or shrink the GPT table to 124 partition entries to make it occupying exact 32 sectors ( using the "s: resize partition table" expert command of gdisk(8) ), and then enlarge this partition by one 512-byte sectors.