firmware: Add context flag for fastboot policy

Fastboot should be available only in certain conditions i.e.:
 - In developer mode including forced with GBB flag
 - In any mode with Fastboot GBB flag enabled

This commit adds a new context flag which is set based on the above
conditions.

BRANCH=None
BUG=b:484260435
TEST=make runtests # In CrOS-SDK
TEST=Verify that fastboot is unavailable w/o disabling OEM Lock or
setting GBB flags

Change-Id: I70bc431785d1b802231b8a0b363cf8cf0fd0e8a1
Signed-off-by: Jakub Czapiga <czapiga@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/7689794
Reviewed-by: Tomasz Michalec <tmichalec@google.com>
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index d92ca55..2c63967 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -608,6 +608,16 @@
 	    (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_ALTFW) ||
 	    vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_ALTFW))
 		ctx->flags |= VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED;
+
+	/*
+	 * Allow fastboot in:
+	 *  - Developer mode including forced by GBB flag
+	 *  - Any mode with Fastboot GBB flag enabled
+	 */
+	if ((ctx->boot_mode == VB2_BOOT_MODE_DEVELOPER &&
+	     (ctx->flags & VB2_CONTEXT_DEV_BOOT_ALLOWED)) ||
+	    (vb2api_gbb_get_flags(ctx) & VB2_GBB_FLAG_FORCE_UNLOCK_FASTBOOT))
+		ctx->flags |= VB2_CONTEXT_FASTBOOT_ALLOWED;
 }
 
 int vb2api_use_short_dev_screen_delay(struct vb2_context *ctx)
diff --git a/firmware/2lib/include/2context.h b/firmware/2lib/include/2context.h
index e7420d6..1b2f8e3 100644
--- a/firmware/2lib/include/2context.h
+++ b/firmware/2lib/include/2context.h
@@ -204,6 +204,13 @@
 	 * support two RW slots.
 	 */
 	VB2_CONTEXT_SLOT_A_ONLY = (1 << 29),
+
+	/*
+	 * Fastboot is allowed. Based on boot mode, GBB Flags, and OEM Lock.
+	 *
+	 * See more: b/484260435
+	 */
+	VB2_CONTEXT_FASTBOOT_ALLOWED = (1 << 30),
 };
 
 /* Helper for aligning fields in vb2_context. */
diff --git a/tests/vb2_misc_tests.c b/tests/vb2_misc_tests.c
index 19cbcc3..0d1517d 100644
--- a/tests/vb2_misc_tests.c
+++ b/tests/vb2_misc_tests.c
@@ -1125,6 +1125,81 @@
 	vb2_fill_dev_boot_flags(ctx);
 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALLOWED,
 		  "dev boot - GBB force dev on with OEM lock");
+
+	/* Fastboot - allowed in dev by GBB flag */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
+	gbb.flags |= VB2_GBB_FLAG_FORCE_UNLOCK_FASTBOOT;
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_TRUE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		  "fastboot allowed - dev mode + GBB flag");
+
+	/* Fastboot - allowed in dev by OEM unlock */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
+	vb2_nv_set(ctx, VB2_NV_OEM_LOCK, 0);
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_TRUE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		  "fastboot allowed - dev mode + OEM unlock");
+
+	/* Fastboot - allowed in dev by GBB flag with OEM lock */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
+	gbb.flags |= VB2_GBB_FLAG_FORCE_UNLOCK_FASTBOOT;
+	gbb.flags |= VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON;
+	vb2_nv_set(ctx, VB2_NV_OEM_LOCK, 1);
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_TRUE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		  "fastboot allowed - dev mode + GBB flag + OEM lock + force dev");
+
+	/* Fastboot - not allowed in dev with OEM lock and no GBB flag */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
+	vb2_nv_set(ctx, VB2_NV_OEM_LOCK, 1);
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_FALSE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		   "fastboot not allowed - dev mode + OEM lock + no GBB flag");
+
+	/* Fastboot - not allowed in dev when DEV_BOOT_ALLOWED is disabled */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
+	fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_FALSE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		   "fastboot not allowed - dev mode + FWMP disable boot");
+
+	/* Fastboot - allowed in manual recovery by GBB flag */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY, VB2_RECOVERY_RO_MANUAL);
+	gbb.flags |= VB2_GBB_FLAG_FORCE_UNLOCK_FASTBOOT;
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_TRUE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		  "fastboot allowed - manual recovery + GBB flag");
+
+	/* Fastboot - not allowed in manual recovery with OEM unlock but no GBB flag */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY, VB2_RECOVERY_RO_MANUAL);
+	vb2_nv_set(ctx, VB2_NV_OEM_LOCK, 0);
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_FALSE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		   "fastboot not allowed - manual recovery + OEM unlock + no GBB flag");
+
+	/* Fastboot - allowed in normal mode by GBB flag */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
+	gbb.flags |= VB2_GBB_FLAG_FORCE_UNLOCK_FASTBOOT;
+	vb2_nv_set(ctx, VB2_NV_OEM_LOCK, 0);
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_TRUE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		   "fastboot allowed - normal mode + GBB flag");
+
+	/* Fastboot - not allowed in normal mode by OEM Lock and not GBB flag */
+	reset_common_data();
+	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
+	vb2_nv_set(ctx, VB2_NV_OEM_LOCK, 1);
+	vb2_fill_dev_boot_flags(ctx);
+	TEST_FALSE(ctx->flags & VB2_CONTEXT_FASTBOOT_ALLOWED,
+		   "fastboot not allowed - normal mode + OEM lock + no GBB flag");
 }
 
 static void use_dev_screen_short_delay_tests(void)