luks: Add detection of LUKS partition

Provide a function which can detect a LUKS partition. Add a test, using
mmc11

Series-to: concept
Cover-letter:
luks: Provide basic support for unlocking a LUKS1 partition
With full-disk encryption (FDE) it is traditional to unlock a LUKS
partition within userspace as part of the initial ramdisk passed to
Linux. The user is prompted for a passphrase and then the disk is
unlocked.

This works well but does have some drawbacks:
- firmware has no way of knowing whether the boot will success
- the 'passphrase' prompt comes quite late in the boot, which can be
  confusing for the user
- specifically it is not possible to provide an integrated 'boot' UI in
  firmware where the user can enter the passphrase
- in a VM environment, the key may be known in advance, but there is no
  way to take advantage of this
- it is not possible to use an encryted disk unless also using a ramdisk

This series makes a small step towards improving U-Boot in this area. It
allows a passphrase to be checked against a LUKS1-encrypted partition.
It also provides read-only access to the unencrypted data, so that files
can be read.
END

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-10-21 11:14:04 +01:00
parent fb5cd8627a
commit dfb03773ca
4 changed files with 343 additions and 0 deletions

View File

@@ -1295,6 +1295,7 @@ S: Maintained
T: git https://concept.u-boot.org/u-boot/u-boot.git
F: cmd/luks.c
F: doc/usage/cmd/luks.rst
F: doc/usage/luks.rst
F: drivers/block/luks.c
F: include/luks.h
F: include/json.h

View File

@@ -248,6 +248,7 @@ if unlock failed (wrong passphrase, unsupported format, etc.).
See also
--------
* :doc:`../luks` - Comprehensive LUKS feature documentation
* :doc:`blkmap` - Blkmap device documentation
* cryptsetup project: https://gitlab.com/cryptsetup/cryptsetup
* LUKS on-disk format specifications: https://gitlab.com/cryptsetup/cryptsetup/-/wikis/home

View File

@@ -11,6 +11,7 @@ Use U-Boot
environment
fdt_overlays
fit/index
luks
netconsole
partitions
cmdline

340
doc/usage/luks.rst Normal file
View File

@@ -0,0 +1,340 @@
.. SPDX-License-Identifier: GPL-2.0+
LUKS (Linux Unified Key Setup)
===============================
Overview
--------
U-Boot provides support for accessing LUKS-encrypted partitions through the
``luks`` command and the blkmap device infrastructure. This allows U-Boot to
unlock and read data from LUKS1-encrypted block devices.
LUKS is a standard for disk encryption that stores encryption metadata in a
header on the encrypted device. It supports multiple key slots, allowing
different passphrases to unlock the same encrypted data.
Currently, U-Boot supports:
* LUKS version 1 (LUKS1)
* AES-256-CBC encryption with ESSIV (Encrypted Salt-Sector IV) mode
* Passphrase-based unlocking via PBKDF2 key derivation
* Reading ext4 and other filesystems from unlocked devices
Supported Cipher Modes
-----------------------
The following LUKS1 cipher configurations are supported:
* **Cipher**: aes
* **Mode**: cbc-essiv:sha256
* **Key sizes**: 128-bit, 192-bit, 256-bit
* **Hash**: sha256 (for PBKDF2)
Commands
--------
See the :doc:`cmd/luks` for full details.
luks detect
~~~~~~~~~~~
Detect whether a partition is LUKS-encrypted::
luks detect <interface> <dev[:part]>
Example::
=> luks detect mmc 0:2
LUKS1 encrypted partition detected
This command checks for the LUKS magic bytes and validates the header structure.
luks info
~~~~~~~~~
Display information about a LUKS partition::
luks info <interface> <dev[:part]>
Example::
=> luks info mmc 0:2
Version: 1
Cipher name: aes
Cipher mode: cbc-essiv:sha256
Hash spec: sha256
Payload offset: 4096
Key bytes: 32
This shows the LUKS header metadata including encryption parameters and the
offset to the encrypted data payload.
luks unlock
~~~~~~~~~~~
Unlock a LUKS partition with a passphrase::
luks unlock <interface> <dev[:part]> <passphrase>
Example::
=> luks unlock mmc 0:2 mypassword
Trying to unlock LUKS partition...
Key size: 32 bytes
Trying key slot 0...
Successfully unlocked with key slot 0!
Unlocked LUKS partition as blkmap device 'luks-mmc-0:2'
Access decrypted data via: blkmap 0
This command:
1. Reads the LUKS header from the specified partition
2. Derives the encryption key from the passphrase using PBKDF2
3. Attempts to unlock each active key slot
4. Verifies the unlocked key against the master key digest
5. Creates a blkmap device that provides on-the-fly decryption
Accessing Unlocked Data
------------------------
After unlocking, the decrypted data is accessible through a blkmap device.
The device number is shown in the unlock output (typically ``blkmap 0``).
Listing Files
~~~~~~~~~~~~~
Use standard filesystem commands to access the unlocked device::
=> ls blkmap 0 /
./
../
lost+found/
221 README.md
17 hello.txt
subdir/
20 test.txt
3 file(s), 4 dir(s)
Reading Files
~~~~~~~~~~~~~
Read file contents::
=> cat blkmap 0 /hello.txt
Hello from LUKS!
Loading Files to Memory
~~~~~~~~~~~~~~~~~~~~~~~~
Load files for further processing::
=> ext4load blkmap 0 ${loadaddr} /boot/vmlinuz
5242880 bytes read in 123 ms (40.6 MiB/s)
Using with Boot Flows
~~~~~~~~~~~~~~~~~~~~~
LUKS-encrypted partitions can be integrated into boot flows::
=> bootflow scan
=> bootflow list
The bootflow will detect filesystems on unlocked blkmap devices.
Implementation Details
----------------------
Key Derivation
~~~~~~~~~~~~~~
LUKS uses PBKDF2 (Password-Based Key Derivation Function 2) to derive
encryption keys from passphrases. The process:
1. Passphrase + salt → PBKDF2 → derived key
2. Derived key decrypts the AF-split key material
3. AF-merge combines the split key material → master key
4. Master key digest is verified against stored value
Anti-Forensic (AF) Splitter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LUKS uses an anti-forensic information splitter to protect key material:
* The master key is split into 4000 stripes
* Each stripe is XORed and hashed with a counter
* All stripes must be recovered to reconstruct the key
* This makes recovery from partial key material extremely difficult
ESSIV Mode
~~~~~~~~~~
ESSIV (Encrypted Salt-Sector IV) generates unique initialization vectors
for each encrypted sector:
1. ESSIV key = SHA256(master_key)
2. For each sector: IV = AES_encrypt(sector_number, ESSIV_key)
3. Data is encrypted: ciphertext = AES-CBC-encrypt(plaintext, master_key, IV)
This prevents watermarking attacks where identical plaintext blocks would
produce identical ciphertext blocks.
Blkmap Device Mapping
~~~~~~~~~~~~~~~~~~~~~
When a LUKS partition is unlocked, U-Boot creates a blkmap device that:
* Maps to the underlying encrypted device
* Performs on-the-fly AES-CBC decryption with ESSIV
* Presents decrypted data as a standard block device
* Supports whole-disk filesystems (no partition table required)
The blkmap device number can be used with any U-Boot command that accepts
block device specifications.
Creating LUKS Partitions for Testing
-------------------------------------
Using cryptsetup on Linux::
# Create a 60MB file
$ dd if=/dev/zero of=test.img bs=1M count=60
# Format as LUKS1
$ cryptsetup luksFormat --type luks1 \
--cipher aes-cbc-essiv:sha256 \
--key-size 256 \
--hash sha256 \
test.img
# Open the LUKS device
$ cryptsetup open test.img testluks
# Create filesystem
$ mkfs.ext4 /dev/mapper/testluks
# Mount and add files
$ mount /dev/mapper/testluks /mnt
$ echo "Hello from LUKS!" > /mnt/hello.txt
$ umount /mnt
# Close the LUKS device
$ cryptsetup close testluks
Using Python with U-Boot Test Infrastructure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See ``test/py/tests/fs_helper.py`` for the ``FsHelper`` class::
from fs_helper import FsHelper, DiskHelper
# Create encrypted filesystem
with FsHelper(config, 'ext4', 30, 'test',
part_mb=60,
encrypt_passphrase='mypassword') as fsh:
# Add files to fsh.srcdir
with open(os.path.join(fsh.srcdir, 'hello.txt'), 'w') as f:
f.write('Hello from LUKS!\n')
# Create encrypted filesystem
fsh.mk_fs()
Configuration Options
---------------------
CONFIG_CMD_LUKS
Enable the ``luks`` command
CONFIG_BLKMAP
Enable blkmap device support (required for LUKS unlock)
CONFIG_AES
Enable AES encryption support
CONFIG_SHA256
Enable SHA-256 hashing support
CONFIG_PBKDF2
Enable PBKDF2 key derivation
Limitations
-----------
* Only LUKS1 is currently supported (LUKS2 not yet implemented)
* Only AES-CBC-ESSIV cipher mode is supported
* Only passphrase-based unlocking is supported (no key files)
* Unlocked devices are read-only (write support not yet implemented)
* Master key remains in memory after unlocking (not securely erased on exit)
Security Considerations
-----------------------
Passphrase Handling
~~~~~~~~~~~~~~~~~~~
* Passphrases are passed as command-line arguments
* They may be visible in command history
* Consider using environment variables or scripts to minimize exposure
Memory Security
~~~~~~~~~~~~~~~
* Master keys are wiped from stack after use where possible
* Keys remain in blkmap device structure while device is active
* No secure memory protection or key erasure on warm reboot
Intended Use Cases
~~~~~~~~~~~~~~~~~~
U-Boot's LUKS support is intended for:
* Boot-time access to encrypted root filesystems
* Reading configuration from encrypted partitions
* Testing and development of encrypted disk support
It is **not** a replacement for full disk encryption solutions in production
operating systems.
Example Use Cases
-----------------
Encrypted Root Filesystem
~~~~~~~~~~~~~~~~~~~~~~~~~
Boot from an encrypted root partition::
=> luks unlock mmc 0:2 ${rootfs_password}
=> setenv bootargs root=/dev/blkmap0 rootfstype=ext4
=> ext4load blkmap 0 ${kernel_addr_r} /boot/vmlinuz
=> ext4load blkmap 0 ${ramdisk_addr_r} /boot/initrd.img
=> bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
Encrypted Configuration Storage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Read configuration from encrypted partition::
=> luks unlock mmc 0:3 ${config_password}
=> ext4load blkmap 0 ${loadaddr} /config/boot.conf
=> env import -t ${loadaddr} ${filesize}
Testing
-------
See ``test/boot/luks.c`` for tests:
* LUKS detection on encrypted and non-encrypted partitions
* LUKS header information parsing
* Successful unlocking with correct passphrase
* Rejection of incorrect passphrases
* Blkmap device creation and filesystem access
See Also
--------
* :doc:`cmd/luks` - LUKS command reference
* :doc:`cmd/blkmap` - Blkmap command reference
* :doc:`blkmap` - Blkmap device documentation
* ``test/py/tests/fs_helper.py`` - Filesystem helper for creating test images
* Linux ``cryptsetup`` documentation for LUKS disk format specification