luks: Show the JSON information for LUKSv2

Extract the full information for version 2, which is JSON format. Show
this with the 'luks info' command.

Use the mmc12 disk to check this.

Require the JSON for LUKS.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-10-23 13:22:56 +01:00
parent eb2ae89f55
commit 22826bf21f
4 changed files with 165 additions and 6 deletions

View File

@@ -106,6 +106,35 @@ Display LUKS header information for a LUKS2 partition::
Label:
Checksum alg: sha256
JSON metadata (12288 bytes):
{
"keyslots": {
"0": {
"type": "luks2",
"key_size": 64,
"kdf": {
"type": "argon2id",
"time": 6,
"memory": 1048576,
"cpus": 4,
...
},
...
}
},
"tokens": {},
"segments": {
"0": {
"type": "crypt",
"offset": "16777216",
"encryption": "aes-xts-plain64",
...
}
},
"digests": { ... },
"config": { ... }
}
Display LUKS header information for a LUKS1 partition::
=> luks info mmc 1:1

View File

@@ -278,6 +278,7 @@ config BLK_LUKS
select SHA256
select PBKDF2
select PKCS5_MBEDTLS if MBEDTLS_LIB_CRYPTO
select JSON
help
This provides support for detecting and decrypting LUKS (Linux Unified
Key Setup) encrypted partitions. LUKS is a disk encryption specification

View File

@@ -8,6 +8,7 @@
#include <blk.h>
#include <dm.h>
#include <hexdump.h>
#include <json.h>
#include <log.h>
#include <luks.h>
#include <memalign.h>
@@ -103,6 +104,28 @@ int luks_show_info(struct udevice *blk, struct disk_partition *pinfo)
printf("UUID: %.40s\n", luks2_hdr->uuid);
printf("Label: %.48s\n", luks2_hdr->label);
printf("Checksum alg: %.32s\n", luks2_hdr->csum_alg);
if (IS_ENABLED(CONFIG_JSON)) {
u64 json_size;
char *json_start;
int blocks;
/* Read the full header to get JSON area */
blocks = (hdr_size + desc->blksz - 1) / desc->blksz;
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, full_hdr, blocks * desc->blksz);
if (blk_read(blk, pinfo->start, blocks, full_hdr) != blocks) {
printf("Error: failed to read full LUKS2 header\n");
return -EIO;
}
/* JSON starts after the 4096-byte binary header */
json_start = (char *)(full_hdr + 4096);
json_size = hdr_size - 4096;
printf("\nJSON metadata (%llx bytes):\n", json_size);
json_print_pretty(json_start, (int)json_size);
}
} else {
printf("Unknown LUKS version\n");
return -EPROTONOSUPPORT;

View File

@@ -20,19 +20,49 @@
DECLARE_GLOBAL_DATA_PTR;
/* Common function to setup mmc11 device */
static int setup_mmc11(struct unit_test_state *uts, struct udevice **mmcp)
/**
* setup_mmc_device() - Set up an MMC device for testing
*
* This function binds and probes an MMC device specified by its device tree
* node name. It is used to prepare MMC devices containing test disk images
* with various configurations (e.g., LUKS1, LUKS2 encryption).
*
* @uts: Unit test state
* @node_name: Name of the device tree node (e.g., "mmc11", "mmc12")
* @mmcp: Returns pointer to the MMC device
* Return: 0 if OK, -ve on error
*/
static int setup_mmc_device(struct unit_test_state *uts, const char *node_name,
struct udevice **mmcp)
{
struct udevice *mmc;
ofnode root, node;
/* Enable the mmc11 node */
/* Enable the specified mmc node */
root = oftree_root(oftree_default());
node = ofnode_find_subnode(root, "mmc11");
node = ofnode_find_subnode(root, node_name);
ut_assert(ofnode_valid(node));
ut_assertok(lists_bind_fdt(gd->dm_root, node, mmcp, NULL, false));
ut_assertok(lists_bind_fdt(gd->dm_root, node, &mmc, NULL, false));
/* Probe the device */
ut_assertok(device_probe(*mmcp));
ut_assertok(device_probe(mmc));
*mmcp = mmc;
return 0;
}
/* Setup mmc11 device */
static int setup_mmc11(struct unit_test_state *uts, struct udevice **mmcp)
{
ut_assertok(setup_mmc_device(uts, "mmc11", mmcp));
return 0;
}
/* Setup mmc12 device */
static int setup_mmc12(struct unit_test_state *uts, struct udevice **mmcp)
{
ut_assertok(setup_mmc_device(uts, "mmc12", mmcp));
return 0;
}
@@ -107,3 +137,79 @@ static int bootstd_test_luks_info(struct unit_test_state *uts)
return 0;
}
BOOTSTD_TEST(bootstd_test_luks_info, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
/* Test LUKSv2 detection on mmc12 partitions */
static int bootstd_test_luks2_detect(struct unit_test_state *uts)
{
struct disk_partition info;
struct blk_desc *desc;
struct udevice *mmc;
int ret;
ut_assertok(setup_mmc12(uts, &mmc));
desc = blk_get_by_device(mmc);
ut_assertnonnull(desc);
ut_assertnonnull(desc->bdev);
/* Check partition 1 - should NOT be LUKS */
ut_assertok(part_get_info(desc, 1, &info));
ret = luks_detect(desc->bdev, &info);
ut_assert(ret < 0); /* Should fail - not LUKS */
/* Check partition 2 - should BE LUKS */
ut_assertok(part_get_info(desc, 2, &info));
ut_assertok(luks_detect(desc->bdev, &info));
/* Verify it's LUKS version 2 */
ut_asserteq(2, luks_get_version(desc->bdev, &info));
return 0;
}
BOOTSTD_TEST(bootstd_test_luks2_detect, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
/* Test LUKSv2 command on mmc12 partitions */
static int bootstd_test_luks2_cmd(struct unit_test_state *uts)
{
struct udevice *mmc;
ut_assertok(setup_mmc12(uts, &mmc));
/* Test partition 1 - should NOT be LUKS */
ut_asserteq(1, run_command("luks detect mmc c:1", 0));
ut_assert_nextlinen("Not a LUKS partition (error -");
ut_assert_console_end();
/* Test partition 2 - should BE LUKS */
ut_assertok(run_command("luks detect mmc c:2", 0));
ut_assert_nextline("LUKS2 encrypted partition detected");
ut_assert_console_end();
return 0;
}
BOOTSTD_TEST(bootstd_test_luks2_cmd, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
/* Test LUKSv2 info command on mmc12 partition 2 */
static int bootstd_test_luks2_info(struct unit_test_state *uts)
{
struct udevice *mmc;
ut_assertok(setup_mmc12(uts, &mmc));
/* Test partition 2 LUKS info */
ut_assertok(run_command("luks info mmc c:2", 0));
ut_assert_nextline("Version: 2");
ut_assert_nextlinen("Header size:");
ut_assert_nextlinen("Sequence ID:");
ut_assert_nextlinen("UUID:");
ut_assert_nextlinen("Label:");
ut_assert_nextlinen("Checksum alg:");
/* Verify JSON metadata section is present (skip empty line first) */
ut_assert_skip_to_line("");
ut_assert_nextlinen("JSON metadata (");
ut_assert_nextline("{");
/* JSON output varies and there is little value in checking it here */
return 0;
}
BOOTSTD_TEST(bootstd_test_luks2_info, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);