vboot: create secdata_kernel flag to disable diagnostic UI

Diagnostic UI is currently not ready to ship. Disable
the UI (including both entry point and the UI itself)
until it is ready.

Also remove unused mock_presence from vboot_api_kernel4_tests.

BUG=b:155848434, b:162486211
TEST=make clean && make runtests
BRANCH=none

Signed-off-by: Joel Kitching <kitching@google.com>
Change-Id: I5cad7d40b2f52015f17f930a4d061c9cdf976a49
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2328985
Tested-by: Chun-ta Lin <itspeter@chromium.org>
Commit-Queue: Chun-ta Lin <itspeter@chromium.org>
Reviewed-by: Joel Kitching <kitching@chromium.org>
diff --git a/firmware/2lib/2kernel.c b/firmware/2lib/2kernel.c
index dd91ec8..02ea544 100644
--- a/firmware/2lib/2kernel.c
+++ b/firmware/2lib/2kernel.c
@@ -143,10 +143,11 @@
 		return rv;
 	}
 
-	/* Enable phone recovery while disabling the UI */
+	/* Enable phone recovery while disabling the UI; disable diagnostics. */
 	secdata_flags = vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS);
 	secdata_flags &= ~VB2_SECDATA_KERNEL_FLAG_PHONE_RECOVERY_DISABLED;
 	secdata_flags |= VB2_SECDATA_KERNEL_FLAG_PHONE_RECOVERY_UI_DISABLED;
+	secdata_flags |= VB2_SECDATA_KERNEL_FLAG_DIAGNOSTIC_UI_DISABLED;
 	vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS, secdata_flags);
 
 	/* Read kernel version from secdata. */
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index 8e5444a..7c4ca26 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -517,6 +517,12 @@
 		 VB2_SECDATA_KERNEL_FLAG_PHONE_RECOVERY_UI_DISABLED);
 }
 
+int vb2api_diagnostic_ui_enabled(struct vb2_context *ctx)
+{
+	return !(vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS) &
+		 VB2_SECDATA_KERNEL_FLAG_DIAGNOSTIC_UI_DISABLED);
+}
+
 enum vb2_dev_default_boot_target vb2api_get_dev_default_boot_target(
 	struct vb2_context *ctx)
 {
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index 649ee09..205b289 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -854,6 +854,14 @@
  */
 int vb2api_phone_recovery_ui_enabled(struct vb2_context *ctx);
 
+/**
+ * Whether diagnostic UI functionality is enabled or not.
+ *
+ * @param ctx		Vboot context
+ * @return 1 if enabled, 0 if disabled.
+ */
+int vb2api_diagnostic_ui_enabled(struct vb2_context *ctx);
+
 /* Default boot target in developer mode. */
 enum vb2_dev_default_boot_target {
 	/* Default to boot from internal disk. */
diff --git a/firmware/2lib/include/2secdata.h b/firmware/2lib/include/2secdata.h
index 3b2fa3c..425dcff 100644
--- a/firmware/2lib/include/2secdata.h
+++ b/firmware/2lib/include/2secdata.h
@@ -100,6 +100,13 @@
 
 	/* Phone recovery instructions in recovery UI are disabled. */
 	VB2_SECDATA_KERNEL_FLAG_PHONE_RECOVERY_UI_DISABLED = (1 << 1),
+
+	/*
+	 * Diagnostic UI is disabled.  This includes both hiding the entry
+	 * point on the recovery UI menu ("Launch diagnostics"), and
+	 * disallowing the user from booting into the diagnostic UI.
+	 */
+	VB2_SECDATA_KERNEL_FLAG_DIAGNOSTIC_UI_DISABLED = (1 << 2),
 };
 
 /**
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 500d372..4ae52c5 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -241,6 +241,7 @@
 			VB2_TRY(VbBootRecoveryLegacyClamshell(ctx));
 		}
 	} else if (DIAGNOSTIC_UI && !MENU_UI &&
+		   vb2api_diagnostic_ui_enabled(ctx) &&
 		   vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST)) {
 		vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 0);
 
diff --git a/tests/vb2_kernel_tests.c b/tests/vb2_kernel_tests.c
index 216776d..c2741b4 100644
--- a/tests/vb2_kernel_tests.c
+++ b/tests/vb2_kernel_tests.c
@@ -218,6 +218,9 @@
 		"  phone recovery enabled");
 	TEST_EQ(vb2api_phone_recovery_ui_enabled(ctx), 0,
 		"  phone recovery ui disabled");
+	/* Make sure diagnostic UI is disabled */
+	TEST_EQ(vb2api_diagnostic_ui_enabled(ctx), 0,
+		"  diagnostic ui disabled");
 
 	/* Bad secdata_fwmp causes failure in normal mode only */
 	reset_common_data(FOR_PHASE1);
diff --git a/tests/vb2_misc_tests.c b/tests/vb2_misc_tests.c
index 0f89ee5..c64552c 100644
--- a/tests/vb2_misc_tests.c
+++ b/tests/vb2_misc_tests.c
@@ -866,6 +866,24 @@
 		"  ui disabled");
 }
 
+static void diagnostic_ui_enabled_tests(void)
+{
+	reset_common_data();
+	vb2api_secdata_kernel_create(ctx);
+	vb2_secdata_kernel_init(ctx);
+	TEST_EQ(vb2api_diagnostic_ui_enabled(ctx), 1,
+		"diagnostic UI enabled");
+
+	reset_common_data();
+	vb2api_secdata_kernel_create(ctx);
+	vb2_secdata_kernel_init(ctx);
+	vb2_secdata_kernel_set(
+		ctx, VB2_SECDATA_KERNEL_FLAGS,
+		VB2_SECDATA_KERNEL_FLAG_DIAGNOSTIC_UI_DISABLED);
+	TEST_EQ(vb2api_diagnostic_ui_enabled(ctx), 0,
+		"diagnostic UI disabled");
+}
+
 static void dev_default_boot_tests(void)
 {
 	/* No default boot */
@@ -1048,6 +1066,7 @@
 	clear_recovery_tests();
 	get_recovery_reason_tests();
 	phone_recovery_enabled_tests();
+	diagnostic_ui_enabled_tests();
 	dev_default_boot_tests();
 	dev_boot_allowed_tests();
 	use_dev_screen_short_delay_tests();
diff --git a/tests/vboot_api_kernel4_tests.c b/tests/vboot_api_kernel4_tests.c
index 0a07b38..44021c8 100644
--- a/tests/vboot_api_kernel4_tests.c
+++ b/tests/vboot_api_kernel4_tests.c
@@ -40,8 +40,7 @@
 static uint32_t current_recovery_reason;
 static uint32_t expected_recovery_reason;
 
-static uint32_t mock_presence[8];
-static uint32_t mock_presence_count;
+static int mock_diagnostic_ui_enabled;
 
 static void reset_common_data(void)
 {
@@ -71,8 +70,7 @@
 	current_recovery_reason = 0;
 	expected_recovery_reason = 0;
 
-	memset(mock_presence, 0, sizeof(mock_presence));
-	mock_presence_count = 0;
+	mock_diagnostic_ui_enabled = 0;
 
 	sd->status |= VB2_SD_STATUS_SECDATA_KERNEL_INIT;
 	sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;
@@ -180,12 +178,9 @@
 	return vbboot_retval;
 }
 
-int vb2ex_physical_presence_pressed(void)
+int vb2api_diagnostic_ui_enabled(struct vb2_context *c)
 {
-	if (mock_presence_count < ARRAY_SIZE(mock_presence))
-		return mock_presence[mock_presence_count++];
-	else
-		return 0;
+	return mock_diagnostic_ui_enabled;
 }
 
 vb2_error_t vb2ex_tpm_set_mode(enum vb2_tpm_mode mode_val)
@@ -250,13 +245,18 @@
 	/* Check that NV_DIAG_REQUEST triggers diagnostic UI */
 	if (DIAGNOSTIC_UI) {
 		reset_common_data();
-		mock_presence[1] = 1;
+		mock_diagnostic_ui_enabled = 1;
 		vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1);
 		vbboot_retval = -4;
 		test_slk(VB2_ERROR_MOCK, 0,
-			 "Normal boot with diag");
+			 "Normal boot with diag enabled");
 		TEST_EQ(vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST),
 			0, "  diag not requested");
+
+		reset_common_data();
+		vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1);
+		test_slk(VB2_REQUEST_REBOOT, 0,
+			 "Normal boot with diag disabled (reboot to unset)");
 	}
 
 	/* Boot normal - phase1 failure */