updater: Add quirk for wilco devices

The ME unlock needs a different pattern for these devices.

BUG=b:135216986
BRANCH=none
TEST=test update from unlocked to locked image on sarien

Change-Id: I928ee3de522937d5b972daaec4460dcc731b495e
Signed-off-by: Duncan Laurie <dlaurie@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1659534
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
(cherry picked from commit 24db29e174aa713cab228e3410bb0572331759d5)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1661458
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/futility/updater.h b/futility/updater.h
index 65f0dd4..ffcff47 100644
--- a/futility/updater.h
+++ b/futility/updater.h
@@ -82,6 +82,7 @@
 	QUIRK_ENLARGE_IMAGE,
 	QUIRK_MIN_PLATFORM_VERSION,
 	QUIRK_UNLOCK_ME_FOR_UPDATE,
+	QUIRK_UNLOCK_WILCO_ME_FOR_UPDATE,
 	QUIRK_DAISY_SNOW_DUAL_MODEL,
 	QUIRK_EVE_SMM_STORE,
 	QUIRK_ALLOW_EMPTY_WLTAG,
diff --git a/futility/updater_quirks.c b/futility/updater_quirks.c
index 076730a..54795c1 100644
--- a/futility/updater_quirks.c
+++ b/futility/updater_quirks.c
@@ -37,6 +37,11 @@
 	{ .match = "Google_Eve.",
 	  .quirks = "unlock_me_for_update,eve_smm_store" },
 
+	{ .match = "Google_Sarien.",
+	  .quirks = "unlock_wilco_me_for_update" },
+	{ .match = "Google_Arcada.",
+	  .quirks = "unlock_wilco_me_for_update" },
+
 	{ .match = "Google_Poppy.", .quirks = "min_platform_version=6" },
 	{ .match = "Google_Scarlet.", .quirks = "min_platform_version=1" },
 
@@ -141,6 +146,36 @@
 }
 
 /*
+ * Quirk to unlock a firmware image with SI_ME (management engine) when updating
+ * so the system has a chance to make sure SI_ME won't be corrupted on next boot
+ * before locking the Flash Master values in SI_DESC.
+ * Returns 0 on success, otherwise failure.
+ */
+static int quirk_unlock_wilco_me_for_update(struct updater_config *cfg)
+{
+	struct firmware_section section;
+	struct firmware_image *image_to = &cfg->image;
+	const int flash_master_offset = 128;
+	const uint8_t flash_master[] = {
+		0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff
+	};
+
+	find_firmware_section(&section, image_to, FMAP_SI_DESC);
+	if (section.size < flash_master_offset + ARRAY_SIZE(flash_master))
+		return 0;
+	if (memcmp(section.data + flash_master_offset, flash_master,
+		   ARRAY_SIZE(flash_master)) == 0) {
+		VB2_DEBUG("Target ME not locked.\n");
+		return 0;
+	}
+	INFO("Changed Flash Master Values to unlocked.\n");
+	memcpy(section.data + flash_master_offset, flash_master,
+	       ARRAY_SIZE(flash_master));
+	return 0;
+}
+
+/*
  * Checks and returns 0 if the platform version of current system is larger
  * or equal to given number, otherwise non-zero.
  */
@@ -328,6 +363,11 @@
 			"(also known as Board ID version).";
 	quirks->apply = quirk_min_platform_version;
 
+	quirks = &cfg->quirks[QUIRK_UNLOCK_WILCO_ME_FOR_UPDATE];
+	quirks->name = "unlock_wilco_me_for_update";
+	quirks->help = "Unlock ME for safe lockdown.";
+	quirks->apply = quirk_unlock_wilco_me_for_update;
+
 	quirks = &cfg->quirks[QUIRK_UNLOCK_ME_FOR_UPDATE];
 	quirks->name = "unlock_me_for_update";
 	quirks->help = "b/35568719; only lock management engine in "