[Concept,16/16] boot: Detect encrypted partitions with extlinux

Message ID 20251115185212.539268-17-sjg@u-boot.org
State New
Headers
Series Continue TKey development |

Commit Message

Simon Glass Nov. 15, 2025, 6:52 p.m. UTC
  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(+)
  

Patch

diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c
index 5a4fefbd868..0cc8c2bf9a5 100644
--- a/boot/bootmeth_extlinux.c
+++ b/boot/bootmeth_extlinux.c
@@ -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;
 }
 
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index a1390ad9a6d..55f73cda3ef 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -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);