luks: Add -p flag for pre-derived master key

Add a -p flag to the luks unlock command that allows passing a
hex-encoded pre-derived master key, skipping the KDF step. This is
useful when the master key has been derived externally, such as from a
hardware security module.

Adjust the normal flow (without -p) to use a key derived on the TKey
output. While that works OK with LUKS1, the 32-byte value is not long
enough to work with LUKS2.

Update the documentation to describe the new flag.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
Simon Glass
2025-11-27 07:07:29 -07:00
parent 6873d2bf79
commit 67ed14f985
2 changed files with 47 additions and 13 deletions

View File

@@ -85,10 +85,10 @@ static int unlock_with_tkey(struct blk_desc *dev_desc,
printf("Using TKey for disk encryption key\n");
/* Find TKey device */
ret = uclass_first_device_err(UCLASS_TKEY, &tkey_dev);
if (ret) {
printf("Failed to find TKey device (err %dE)\n", ret);
return ret;
tkey_dev = tkey_get_device();
if (!tkey_dev) {
printf("Failed to find TKey device\n");
return -ENOENT;
}
/* Derive disk key using TKey with passphrase as USS */
@@ -113,7 +113,7 @@ static int unlock_with_tkey(struct blk_desc *dev_desc,
TKEY_DISK_KEY_SIZE, false);
ret = luks_unlock(dev_desc->bdev, info, tkey_disk_key,
TKEY_DISK_KEY_SIZE, true, master_key, key_size);
TKEY_DISK_KEY_SIZE, false, master_key, key_size);
/* Wipe TKey disk key */
memset(tkey_disk_key, '\0', sizeof(tkey_disk_key));
@@ -129,14 +129,21 @@ static int do_luks_unlock(struct cmd_tbl *cmdtp, int flag, int argc,
struct udevice *blkmap_dev;
const char *passphrase = NULL;
bool use_tkey = false;
bool pre_derived = false;
int part, ret, version;
u8 master_key[128];
char label[64];
u32 key_size;
/* Check for -t flag */
if (!strcmp(argv[1], "-t")) {
use_tkey = true;
/* Check for flags */
while (argc > 1 && argv[1][0] == '-') {
if (!strcmp(argv[1], "-t")) {
use_tkey = true;
} else if (!strcmp(argv[1], "-p")) {
pre_derived = true;
} else {
return CMD_RET_USAGE;
}
argc--;
argv++;
}
@@ -165,9 +172,21 @@ static int do_luks_unlock(struct cmd_tbl *cmdtp, int flag, int argc,
if (use_tkey) {
ret = unlock_with_tkey(dev_desc, &info, passphrase, master_key,
&key_size);
} else if (pre_derived) {
/* Pre-derived key: passphrase is hex-encoded master key */
u8 key_buf[64];
size_t key_len = strlen(passphrase) / 2;
if (key_len > sizeof(key_buf) || hex2bin(key_buf, passphrase,
key_len)) {
printf("Invalid hex key\n");
return CMD_RET_FAILURE;
}
ret = luks_unlock(dev_desc->bdev, &info, key_buf, key_len,
true, master_key, &key_size);
} else {
/* Unlock with passphrase */
ret = luks_unlock(dev_desc->bdev, &info,(const u8 *)passphrase,
ret = luks_unlock(dev_desc->bdev, &info, (const u8 *)passphrase,
strlen(passphrase), false, master_key,
&key_size);
}
@@ -202,8 +221,9 @@ cleanup:
static char luks_help_text[] =
"detect <interface> <dev[:part]> - detect if partition is LUKS encrypted\n"
"luks info <interface> <dev[:part]> - show LUKS header information\n"
"luks unlock [-t] <interface> <dev[:part]> <passphrase> - unlock LUKS partition\n"
" -t: Use TKey hardware security token with passphrase as USS\n";
"luks unlock [-t] [-p] <interface> <dev[:part]> <passphrase> - unlock LUKS partition\n"
" -t: Use TKey hardware security token with passphrase as USS\n"
" -p: Treat passphrase as hex-encoded pre-derived master key (skip KDF)\n";
U_BOOT_CMD_WITH_SUBCMDS(luks, "LUKS (Linux Unified Key Setup) operations",
luks_help_text,

View File

@@ -13,7 +13,7 @@ Synopsis
luks detect <interface> <dev[:part]>
luks info <interface> <dev[:part]>
luks unlock [-t] <interface> <dev[:part]> <passphrase>
luks unlock [-t] [-p] <interface> <dev[:part]> <passphrase>
Description
-----------
@@ -97,7 +97,8 @@ This command:
- **Without -t**: Uses PBKDF2 or Argon2id with the provided passphrase
- **With -t**: Uses TKey hardware token with passphrase as USS (User-Supplied
Secret) to derive a disk encryption key
Secret) to derive a disk encryption key. You can use 'tkey connect' to
select which TKey to use, otherwise it uses the first one it finds.
4. Attempts to unlock each active key slot
5. Verifies the master key against the stored digest
@@ -128,6 +129,12 @@ be used to access files on the unlocked partition.
passphrase is used as the USS (User-Supplied Secret) to derive a disk
encryption key from the TKey's public key.
-p
Optional flag to treat the passphrase as a hex-encoded pre-derived master
key, skipping the KDF (Key Derivation Function) step. This is useful when
the master key has already been derived externally, such as from a hardware
security module or other key management system.
interface
The storage interface type (e.g., mmc, usb, scsi)
@@ -250,6 +257,13 @@ Unlock using TKey hardware token::
Successfully unlocked with key slot 0!
Unlocked LUKS partition as blkmap device 'luks-mmc-0:2'
Unlock using a pre-derived master key (hex-encoded)::
=> luks unlock -p mmc 0:2 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Unlocking LUKS2 partition...
Successfully unlocked with key slot 0!
Unlocked LUKS partition as blkmap device 'luks-mmc-0:2'
Configuration
-------------