From: Simon Glass <simon.glass@canonical.com>
We don't have an explicit indication of whether the root disk is
encrypted or not. For now, try to detect it and set the flag if
found.
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---
boot/bootmeth_extlinux.c | 54 ++++++++++++++++++++++++++++++++++++++++
test/boot/bootflow.c | 38 ++++++++++++++++++++++++++++
2 files changed, 92 insertions(+)
@@ -17,9 +17,11 @@
#include <dm.h>
#include <extlinux.h>
#include <fs_legacy.h>
+#include <luks.h>
#include <malloc.h>
#include <mapmem.h>
#include <mmc.h>
+#include <part.h>
#include <pxe_utils.h>
static int extlinux_get_state_desc(struct udevice *dev, char *buf, int maxsize)
@@ -64,6 +66,54 @@ static int extlinux_check(struct udevice *dev, struct bootflow_iter *iter)
return 0;
}
+/**
+ * extlinux_check_luks() - Check for LUKS encryption on other partitions
+ *
+ * This scans all partitions on the same device to check for LUKS encryption.
+ * If found, it marks this bootflow as encrypted since it likely boots from
+ * an encrypted root partition.
+ *
+ * @bflow: Bootflow to potentially mark as encrypted
+ * Return: 0 on success, -ve on error
+ */
+static int extlinux_check_luks(struct bootflow *bflow)
+{
+ struct blk_desc *desc;
+ struct disk_partition info;
+ int ret, part;
+
+ if (!IS_ENABLED(CONFIG_BLK_LUKS) || !bflow->blk)
+ return 0;
+
+ desc = dev_get_uclass_plat(bflow->blk);
+ if (!desc || !desc->bdev)
+ return 0;
+
+ /*
+ * Check all partitions on this device for LUKS encryption.
+ * Typically partition 1 has the bootloader files and partition 2
+ * has the encrypted root filesystem. Check up to 10 partitions.
+ */
+ for (part = 1; part <= 10; part++) {
+ ret = part_get_info(desc, part, &info);
+ if (ret)
+ continue; /* Partition doesn't exist */
+
+ ret = luks_detect(desc->bdev, &info);
+ if (!ret) {
+ int luks_ver = luks_get_version(desc->bdev, &info);
+
+ log_debug("LUKS partition %d detected (v%d), marking bootflow as encrypted\n",
+ part, luks_ver);
+ bflow->flags |= BOOTFLOWF_ENCRYPTED;
+ bflow->luks_version = luks_ver;
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
/**
* extlinux_fill_info() - Decode the extlinux file to find out its info
*
@@ -158,6 +208,10 @@ static int extlinux_read_bootflow(struct udevice *dev, struct bootflow *bflow)
if (ret)
return log_msg_ret("inf", ret);
+ ret = extlinux_check_luks(bflow);
+ if (ret)
+ return log_msg_ret("luks", ret);
+
return 0;
}
@@ -1770,3 +1770,41 @@ static int bootflow_extlinux_localboot(struct unit_test_state *uts)
return 0;
}
BOOTSTD_TEST(bootflow_extlinux_localboot, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
+
+/* Check 'bootflow info' with encrypted partition on mmc12 */
+static int bootflow_cmd_info_encrypted(struct unit_test_state *uts)
+{
+ /* Enable mmc12 which has LUKS encrypted partition and scan it */
+ ut_assertok(scan_mmc_bootdev(uts, "mmc12", false));
+
+ /* Check for bootflows - should find one on mmc12 */
+ ut_assertok(run_command("bootflow list", 0));
+ ut_assert_nextline("Showing all bootflows");
+ ut_assert_nextlinen("Seq");
+ ut_assert_nextlinen("---");
+ ut_assert_nextlinen(" 0 extlinux");
+ ut_assert_nextline(
+ " 1 extlinux ready mmc 1 %c mmc12.bootdev.part_1 /extlinux/extlinux.conf",
+ IS_ENABLED(CONFIG_BLK_LUKS) ? 'E' : ' ');
+ ut_assert_nextline("--- ----------- ------ -------- ---- - ------------------------ ----------------");
+ ut_assert_nextline("(2 bootflows, 2 valid)");
+ ut_assert_console_end();
+
+ /* Select the mmc12 bootflow and check info shows encryption */
+ ut_assertok(run_command("bootflow select 1", 0));
+ ut_assert_console_end();
+ ut_assertok(run_command("bootflow info", 0));
+ ut_assert_nextline("Name: mmc12.bootdev.part_1");
+ ut_assert_nextline("Device: mmc12.bootdev");
+ ut_assert_nextline("Block dev: mmc12.blk");
+ ut_assert_nextline("Method: extlinux");
+ ut_assert_nextline("State: ready");
+ ut_assert_nextline("Partition: 1");
+ if (IS_ENABLED(CONFIG_BLK_LUKS))
+ ut_assert_nextline("Encrypted: LUKSv2");
+ ut_assert_skip_to_line("Error: 0");
+ ut_assert_console_end();
+
+ return 0;
+}
+BOOTSTD_TEST(bootflow_cmd_info_encrypted, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);