futility: updater: Abort if the unlock_csme_* is used on a locked device

If --quirk unlock_csme_* (or the legacy param --unlock_me) is enabled,
the expected new image will have an unlocked SI_DESC, and that would
cause AP RO verification check to fail if the device is already locked.

Previously, this will cause the updater to switch to RW-only mode.
However, if the factory is always applying the unlock_csme_* quirk then
the RO may be not properly updated in the whole process.

As a result, we should abort if the device is locked and quirk
unlock_csme_* was enabled.

BUG=b:284913015
TEST=FEATURES=test emerge vboot_reference
BRANCH=None

Change-Id: I929b180b3c6b13dd96a4708c1be52bc876c845e6
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4951472
Reviewed-by: Reka Norman <rekanorman@chromium.org>
Reviewed-by: Phoebe Wang <phoebewang@chromium.org>
Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
(cherry picked from commit 2850244ed1d98e92056bf3e3a739291c266d19c5)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4976475
Tested-by: Phoebe Wang <phoebewang@chromium.org>
Reviewed-by: Cheng Yueh <cyueh@chromium.org>
Commit-Queue: Cheng Yueh <cyueh@chromium.org>
Auto-Submit: Phoebe Wang <phoebewang@chromium.org>
diff --git a/futility/updater.c b/futility/updater.c
index c39bc13..6c1abad 100644
--- a/futility/updater.c
+++ b/futility/updater.c
@@ -588,6 +588,15 @@
 	return is_flash_descriptor_locked(current);
 }
 
+/* Returns true if the UNLOCK_CSME_* quirks were requested, otherwise false. */
+static bool is_unlock_csme_requested(struct updater_config *cfg)
+{
+	if (get_config_quirk(QUIRK_UNLOCK_CSME_NISSA, cfg) ||
+	    get_config_quirk(QUIRK_UNLOCK_CSME_EVE, cfg))
+		return true;
+	return false;
+}
+
 /*
  * Checks if the given firmware images are compatible with current platform.
  * In current implementation (following Chrome OS style), we assume the platform
@@ -922,6 +931,7 @@
 	[UPDATE_ERR_ROOT_KEY] = "RW signed by incompatible root key "
 			        "(different from RO).",
 	[UPDATE_ERR_TPM_ROLLBACK] = "RW not usable due to TPM anti-rollback.",
+	[UPDATE_ERR_UNLOCK_CSME] = "The CSME was already locked (b/284913015).",
 	[UPDATE_ERR_UNKNOWN] = "Unknown error.",
 };
 
@@ -1230,6 +1240,8 @@
 
 	if (!done) {
 		if (!wp_enabled && is_ap_ro_locked_with_verification(cfg)) {
+			if (is_unlock_csme_requested(cfg))
+				return UPDATE_ERR_UNLOCK_CSME;
 			WARN("The AP RO is locked with verification turned on so we can't do "
 			     "full update (b/284913015). Fall back to RW-only update.\n");
 			wp_enabled = 1;
diff --git a/futility/updater.h b/futility/updater.h
index 6208296..1d79abb 100644
--- a/futility/updater.h
+++ b/futility/updater.h
@@ -185,6 +185,7 @@
 	UPDATE_ERR_TARGET,
 	UPDATE_ERR_ROOT_KEY,
 	UPDATE_ERR_TPM_ROLLBACK,
+	UPDATE_ERR_UNLOCK_CSME,
 	UPDATE_ERR_UNKNOWN,
 };