luks: Add a subcommand to unlock an encrypted partition

Provide a new 'luks unlock' command which can unlock a LUKS1 partition,
given a passphrase.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-10-24 06:53:04 +01:00
parent 0cbfb2d490
commit fb5cd8627a
3 changed files with 180 additions and 3 deletions

View File

@@ -57,11 +57,77 @@ static int do_luks_info(struct cmd_tbl *cmdtp, int flag, int argc,
return CMD_RET_SUCCESS;
}
static int do_luks_unlock(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
struct blk_desc *dev_desc;
struct disk_partition info;
struct udevice *blkmap_dev;
const char *passphrase;
int part, ret, version;
u8 master_key[128];
char label[64];
u32 key_size;
if (argc != 4)
return CMD_RET_USAGE;
part = blk_get_device_part_str(argv[1], argv[2], &dev_desc, &info, 1);
if (part < 0)
return CMD_RET_FAILURE;
passphrase = argv[3];
/* Verify it's a LUKS partition */
version = luks_get_version(dev_desc->bdev, &info);
if (version < 0) {
printf("Not a LUKS partition\n");
return CMD_RET_FAILURE;
}
if (version != LUKS_VERSION_1) {
printf("Only LUKS1 is currently supported\n");
return CMD_RET_FAILURE;
}
/* Unlock the partition to get the master key */
ret = luks_unlock(dev_desc->bdev, &info, passphrase, master_key,
&key_size);
if (ret) {
printf("Failed to unlock LUKS partition (err %dE)\n", ret);
return CMD_RET_FAILURE;
}
/* Create blkmap device with label based on source device */
snprintf(label, sizeof(label), "luks-%s-%s", argv[1], argv[2]);
/* Create and map the blkmap device */
ret = luks_create_blkmap(dev_desc->bdev, &info, master_key, key_size,
label, &blkmap_dev);
if (ret) {
printf("Failed to create blkmap device (err %dE)\n", ret);
ret = CMD_RET_FAILURE;
goto cleanup;
}
printf("Unlocked LUKS partition as blkmap device '%s'\n", label);
ret = CMD_RET_SUCCESS;
cleanup:
/* Wipe master key from stack */
memset(master_key, '\0', sizeof(master_key));
return ret;
}
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";
"luks info <interface> <dev[:part]> - show LUKS header information\n"
"luks unlock <interface> <dev[:part]> <passphrase> - unlock LUKS partition\n";
U_BOOT_CMD_WITH_SUBCMDS(luks, "LUKS (Linux Unified Key Setup) operations",
luks_help_text,
U_BOOT_SUBCMD_MKENT(detect, 3, 1, do_luks_detect),
U_BOOT_SUBCMD_MKENT(info, 3, 1, do_luks_info));
U_BOOT_SUBCMD_MKENT(info, 3, 1, do_luks_info),
U_BOOT_SUBCMD_MKENT(unlock, 4, 1, do_luks_unlock));