XTS Mode
The block-cipher mode used for storage encryption. Each sector is encrypted with a position-dependent tweak, so identical plaintext at different offsets produces different ciphertext without any per-sector nonce.
XTS (XEX-based tweaked codebook mode with ciphertext stealing) is the block-cipher mode designed for encrypting storage: disks, partitions, and flash. It is what LUKS, BitLocker, FileVault and ESP32 flash encryption all use, and it exists because storage encryption has a constraint ordinary modes cannot meet.
The constraint
Storage encryption must be length-preserving and random-access. A 4096-byte sector must encrypt to exactly 4096 bytes, with no room for an IV or an authentication tag, and any sector must be decryptable on its own without reading the ones before it.
That rules out the usual choices. CBC needs an IV per sector and chains sequentially. CTR needs a nonce, and reusing a counter across two writes to the same sector is catastrophic. GCM needs space for a tag. XTS solves it by deriving the per-block variation from the data's position, which both sides already know and which costs no storage.
How it works
tweak = AES-Enc(Key2, sector_number)
for each 16-byte block j in the sector:
T = tweak * a^j (multiply in GF(2^128))
C_j = AES-Enc(Key1, P_j XOR T) XOR T
Two independent keys, so a 256-bit "AES-XTS" key is two 128-bit AES keys. The tweak is encrypted once per sector and then advanced by a cheap Galois-field multiplication per block. Ciphertext stealing handles a final partial block so the output length matches the input exactly.
The result: the same plaintext written at two different offsets encrypts differently, and rewriting a sector with the same content produces the same ciphertext, which is unavoidable without extra storage.
What it does and does not give you
XTS provides confidentiality only. It has no authentication and no integrity protection whatsoever. Concretely:
- An attacker who can write to the encrypted medium can flip ciphertext bits. They cannot control the resulting plaintext (a modified block decrypts to 16 bytes of unpredictable garbage), but they can corrupt any chosen block, deterministically, at a chosen offset.
- Blocks can be copied, moved or rolled back. Replacing sector 42 with an old copy of sector 42 decrypts perfectly, because the tweak depends only on the position, which has not changed.
- Identical plaintext blocks at the same offset in different sectors encrypt differently, but identical whole sectors at the same address always encrypt identically over time.
This is why storage encryption is always paired with something else. On a device, secure-boot provides the authentication that XTS does not: the flash contents are confidential thanks to XTS, and trustworthy thanks to the signature check.
On ESP32
Flash encryption uses AES-XTS with the flash offset as the tweak, and the key lives in eFuse where software cannot read it back once the read-protect bit is burned. The consequences that matter in practice:
- A dump taken with
esptool read_flashfrom an encrypted device is ciphertext. It shows high flat entropy andbinwalkfinds nothing. - The key is not in the image. Unlike a firmware that XORs itself, there is nothing in the dump to recover it from; the attack surface moves to the fuse configuration and to side channels.
- Flash encryption alone does not stop an attacker from writing a modified image. Only secure boot does. A device with flash encryption enabled and secure boot disabled is confidential and still fully compromisable.
Pitfalls
- Treating XTS as authenticated encryption. It is not, and no configuration makes it so.
- Assuming an encrypted dump means the analysis is over. The fuse settings, the boot mode, the UART bootloader's remaining capabilities and the debug interfaces are all still there.
- Confusing the two halves of the key. An "AES-256-XTS" volume uses two AES-128 keys, not AES-256; the naming causes real confusion in reports.
What it pairs with
flash-encryption covers the ESP32 feature end to end, secure-boot supplies the integrity XTS lacks, efuse is where the key lives, and entropie-concept explains what an encrypted dump looks like.