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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,6 +11,7 @@ Use U-Boot
|
||||
environment
|
||||
fdt_overlays
|
||||
fit/index
|
||||
luks
|
||||
netconsole
|
||||
partitions
|
||||
cmdline
|
||||
|
||||
340
doc/usage/luks.rst
Normal file
340
doc/usage/luks.rst
Normal 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
|
||||
Reference in New Issue
Block a user