[sw/silicon_creator] Update lifecyle_state_t

This change
* Reduces the number of `lifecycle_state_t` variants to 5, i.e. to the
ones that we use in mask rom,
* Adds `lifecycle_raw_state_get()` to get the unprocessed life cycle
state from hardware (mostly for debug purposes),
* Removes `lifecycle_state_name_get()`,
* Updates `mock_lifecycle.h`, and
* Updates call sites and existing tests.

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/boot_data.c b/sw/device/silicon_creator/lib/boot_data.c
index d6f6b1e..15f489a 100644
--- a/sw/device/silicon_creator/lib/boot_data.c
+++ b/sw/device/silicon_creator/lib/boot_data.c
@@ -472,14 +472,7 @@
                                          boot_data_t *boot_data) {
   // TODO(#8778): Default boot data.
   switch (lc_state) {
-    case kLcStateTestUnlocked0:
-    case kLcStateTestUnlocked1:
-    case kLcStateTestUnlocked2:
-    case kLcStateTestUnlocked3:
-    case kLcStateTestUnlocked4:
-    case kLcStateTestUnlocked5:
-    case kLcStateTestUnlocked6:
-    case kLcStateTestUnlocked7:
+    case kLcStateTest:
     case kLcStateDev:
     case kLcStateRma:
       *boot_data = kBootDataDefault;
diff --git a/sw/device/silicon_creator/lib/boot_data_functest.c b/sw/device/silicon_creator/lib/boot_data_functest.c
index e209c1c..a720097 100644
--- a/sw/device/silicon_creator/lib/boot_data_functest.c
+++ b/sw/device/silicon_creator/lib/boot_data_functest.c
@@ -190,7 +190,7 @@
   erase_boot_data_pages();
 
   boot_data_t boot_data;
-  RETURN_IF_ERROR(boot_data_read(kLcStateTestUnlocked0, &boot_data));
+  RETURN_IF_ERROR(boot_data_read(kLcStateTest, &boot_data));
   RETURN_IF_ERROR(check_boot_data(&boot_data, 5));
   return kErrorOk;
 }
diff --git a/sw/device/silicon_creator/lib/drivers/keymgr_functest.c b/sw/device/silicon_creator/lib/drivers/keymgr_functest.c
index a83dcd6..3d7d541 100644
--- a/sw/device/silicon_creator/lib/drivers/keymgr_functest.c
+++ b/sw/device/silicon_creator/lib/drivers/keymgr_functest.c
@@ -272,8 +272,7 @@
   rom_error_t result = kErrorOk;
 
   // This test is expected to run in DEV, PROD or PROD_END states.
-  lifecycle_state_t lc_state = lifecycle_state_get();
-  LOG_INFO("lifecycle state: %s", lifecycle_state_name_get(lc_state));
+  LOG_INFO("lifecycle state: 0x%x", lifecycle_raw_state_get());
 
   // Initialize pwrmgr
   dif_pwrmgr_t pwrmgr;
diff --git a/sw/device/silicon_creator/lib/drivers/lifecycle.c b/sw/device/silicon_creator/lib/drivers/lifecycle.c
index f925b2b..34eb31d 100644
--- a/sw/device/silicon_creator/lib/drivers/lifecycle.c
+++ b/sw/device/silicon_creator/lib/drivers/lifecycle.c
@@ -8,91 +8,67 @@
 #include <stdint.h>
 
 #include "sw/device/lib/base/bitfield.h"
+#include "sw/device/lib/base/hardened.h"
 #include "sw/device/lib/base/macros.h"
 #include "sw/device/silicon_creator/lib/base/sec_mmio.h"
 
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
 #include "lc_ctrl_regs.h"
 
-static const char *const kStateNames[] = {
-    // clang-format off
-    "RAW",
-    "TEST_UNLOCKED0",
-    "TEST_LOCKED0",
-    "TEST_UNLOCKED1",
-    "TEST_LOCKED1",
-    "TEST_UNLOCKED2",
-    "TEST_LOCKED2",
-    "TEST_UNLOCKED3",
-    "TEST_LOCKED3",
-    "TEST_UNLOCKED4",
-    "TEST_LOCKED4",
-    "TEST_UNLOCKED5",
-    "TEST_LOCKED5",
-    "TEST_UNLOCKED6",
-    "TEST_LOCKED6",
-    "TEST_UNLOCKED7",
-    "DEV",
-    "PROD",
-    "PROD_END",
-    "RMA",
-    "SCRAP",
-    "POST_TRANSITION",
-    "ESCALATE",
-    "INVALID",
-    // clang-format on
-};
-
-static_assert(ARRAYSIZE(kStateNames) == kLcStateNumStates,
-              "length of the kStateNames array doesn't match the "
-              "number of states.");
-
-#define LC_ASSERT(a, b) static_assert(a == b, "Bad value for " #a)
-LC_ASSERT(kLcStateRaw, LC_CTRL_LC_STATE_STATE_VALUE_RAW);
-LC_ASSERT(kLcStateTestUnlocked0, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0);
-LC_ASSERT(kLcStateTestLocked0, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED0);
-LC_ASSERT(kLcStateTestUnlocked1, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1);
-LC_ASSERT(kLcStateTestLocked1, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED1);
-LC_ASSERT(kLcStateTestUnlocked2, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2);
-LC_ASSERT(kLcStateTestLocked2, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED2);
-LC_ASSERT(kLcStateTestUnlocked3, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3);
-LC_ASSERT(kLcStateTestLocked3, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED3);
-LC_ASSERT(kLcStateTestUnlocked4, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4);
-LC_ASSERT(kLcStateTestLocked4, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED4);
-LC_ASSERT(kLcStateTestUnlocked5, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5);
-LC_ASSERT(kLcStateTestLocked5, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED5);
-LC_ASSERT(kLcStateTestUnlocked6, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6);
-LC_ASSERT(kLcStateTestLocked6, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED6);
-LC_ASSERT(kLcStateTestUnlocked7, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7);
-LC_ASSERT(kLcStateDev, LC_CTRL_LC_STATE_STATE_VALUE_DEV);
-LC_ASSERT(kLcStateProd, LC_CTRL_LC_STATE_STATE_VALUE_PROD);
-LC_ASSERT(kLcStateProdEnd, LC_CTRL_LC_STATE_STATE_VALUE_PROD_END);
-LC_ASSERT(kLcStateRma, LC_CTRL_LC_STATE_STATE_VALUE_RMA);
-LC_ASSERT(kLcStateScrap, LC_CTRL_LC_STATE_STATE_VALUE_SCRAP);
-LC_ASSERT(kLcStatePostTransition, LC_CTRL_LC_STATE_STATE_VALUE_POST_TRANSITION);
-LC_ASSERT(kLcStateEscalate, LC_CTRL_LC_STATE_STATE_VALUE_ESCALATE);
-LC_ASSERT(kLcStateInvalid, LC_CTRL_LC_STATE_STATE_VALUE_INVALID);
-
 enum {
   kBase = TOP_EARLGREY_LC_CTRL_BASE_ADDR,
 };
 
 lifecycle_state_t lifecycle_state_get(void) {
+  uint32_t raw_state = lifecycle_raw_state_get();
+
+  switch (launder32(raw_state)) {
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0);
+      return kLcStateTest;
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1);
+      return kLcStateTest;
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2);
+      return kLcStateTest;
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3);
+      return kLcStateTest;
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4);
+      return kLcStateTest;
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5);
+      return kLcStateTest;
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6);
+      return kLcStateTest;
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7);
+      return kLcStateTest;
+    case LC_CTRL_LC_STATE_STATE_VALUE_DEV:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_DEV);
+      return kLcStateDev;
+    case LC_CTRL_LC_STATE_STATE_VALUE_PROD:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_PROD);
+      return kLcStateProd;
+    case LC_CTRL_LC_STATE_STATE_VALUE_PROD_END:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_PROD_END);
+      return kLcStateProdEnd;
+    case LC_CTRL_LC_STATE_STATE_VALUE_RMA:
+      HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_RMA);
+      return kLcStateRma;
+    default:
+      HARDENED_UNREACHABLE();
+  }
+}
+
+uint32_t lifecycle_raw_state_get(void) {
   uint32_t value = bitfield_field32_read(
       sec_mmio_read32(kBase + LC_CTRL_LC_STATE_REG_OFFSET),
       LC_CTRL_LC_STATE_STATE_FIELD);
-  return (lifecycle_state_t)value;
-}
-
-const char *lifecycle_state_name_get(lifecycle_state_t lc_state) {
-  // Life cycle state value (`lc_state`) is a 32-bit value that repeats the
-  // 5-bit life cycle state index 6 times.
-  enum { kStateIndexMask = 0x1f };
-  size_t state_index = (uint32_t)lc_state & kStateIndexMask;
-  if (state_index >= kLcStateNumStates) {
-    state_index = kLcStateInvalid & kStateIndexMask;
-  }
-  return kStateNames[state_index];
+  return value;
 }
 
 void lifecycle_device_id_get(lifecycle_device_id_t *device_id) {
diff --git a/sw/device/silicon_creator/lib/drivers/lifecycle.h b/sw/device/silicon_creator/lib/drivers/lifecycle.h
index adaf609..664ca21 100644
--- a/sw/device/silicon_creator/lib/drivers/lifecycle.h
+++ b/sw/device/silicon_creator/lib/drivers/lifecycle.h
@@ -12,111 +12,81 @@
 #endif
 
 /**
- * Lifecycle States.
+ * Lifecycle states.
+ *
+ * This is a condensed version of the 24 possible life cycle states where
+ * TEST_UNLOCKED_* states are mapped to `kLcStateTest` and invalid states where
+ * CPU execution is disabled are omitted.
+ *
+ * Encoding generated with
+ * $ ./util/design/sparse-fsm-encode.py -d 6 -m 5 -n 32 \
+ *     -s 2447090565 --language=c
+ *
+ * Hamming distance histogram:
+ *
+ *  0: --
+ *  1: --
+ *  2: --
+ *  3: --
+ *  4: --
+ *  5: --
+ *  6: --
+ *  7: --
+ *  8: --
+ *  9: --
+ * 10: --
+ * 11: --
+ * 12: --
+ * 13: ||||| (10.00%)
+ * 14: ||||| (10.00%)
+ * 15: --
+ * 16: |||||||||| (20.00%)
+ * 17: |||||||||||||||||||| (40.00%)
+ * 18: ||||| (10.00%)
+ * 19: ||||| (10.00%)
+ * 20: --
+ * 21: --
+ * 22: --
+ * 23: --
+ * 24: --
+ * 25: --
+ * 26: --
+ * 27: --
+ * 28: --
+ * 29: --
+ * 30: --
+ * 31: --
+ * 32: --
+ *
+ * Minimum Hamming distance: 13
+ * Maximum Hamming distance: 19
+ * Minimum Hamming weight: 15
+ * Maximum Hamming weight: 20
  */
-typedef enum LcState {
-  /**
-   * Raw life cycle state after fabrication where all functions are disabled.
-   */
-  kLcStateRaw = 0x0,
+typedef enum lifecycle_state {
   /**
    * Unlocked test state where debug functions are enabled.
+   *
+   * Corresponds to TEST_UNLOCKED_* life cycle states.
    */
-  kLcStateTestUnlocked0 = 1 * 0x2108421,
-  /**
-   * Locked test state where where all functions are disabled.
-   */
-  kLcStateTestLocked0 = 2 * 0x2108421,
-  /**
-   * Unlocked test state where debug functions are enabled.
-   */
-  kLcStateTestUnlocked1 = 3 * 0x2108421,
-  /**
-   * Locked test state where where all functions are disabled.
-   */
-  kLcStateTestLocked1 = 4 * 0x2108421,
-  /**
-   * Unlocked test state where debug functions are enabled.
-   */
-  kLcStateTestUnlocked2 = 5 * 0x2108421,
-  /**
-   * Locked test state where debug all functions are disabled.
-   */
-  kLcStateTestLocked2 = 6 * 0x2108421,
-  /**
-   * Unlocked test state where debug functions are enabled.
-   */
-  kLcStateTestUnlocked3 = 7 * 0x2108421,
-  /**
-   * Locked test state where debug all functions are disabled.
-   */
-  kLcStateTestLocked3 = 8 * 0x2108421,
-  /**
-   * Unlocked test state where debug functions are enabled.
-   */
-  kLcStateTestUnlocked4 = 9 * 0x2108421,
-  /**
-   * Locked test state where debug all functions are disabled.
-   */
-  kLcStateTestLocked4 = 10 * 0x2108421,
-  /**
-   * Unlocked test state where debug functions are enabled.
-   */
-  kLcStateTestUnlocked5 = 11 * 0x2108421,
-  /**
-   * Locked test state where debug all functions are disabled.
-   */
-  kLcStateTestLocked5 = 12 * 0x2108421,
-  /**
-   * Unlocked test state where debug functions are enabled.
-   */
-  kLcStateTestUnlocked6 = 13 * 0x2108421,
-  /**
-   * Locked test state where debug all functions are disabled.
-   */
-  kLcStateTestLocked6 = 14 * 0x2108421,
-  /**
-   * Unlocked test state where debug functions are enabled.
-   */
-  kLcStateTestUnlocked7 = 15 * 0x2108421,
+  kLcStateTest = 0xb2865fbb,
   /**
    * Development life cycle state where limited debug functionality is
    * available.
    */
-  kLcStateDev = 16 * 0x2108421,
+  kLcStateDev = 0x0b5a75e0,
   /**
    * Production life cycle state.
    */
-  kLcStateProd = 17 * 0x2108421,
+  kLcStateProd = 0x65f2520f,
   /**
    * Same as PROD, but transition into RMA is not possible from this state.
    */
-  kLcStateProdEnd = 18 * 0x2108421,
+  kLcStateProdEnd = 0x91b9b68a,
   /**
    * RMA life cycle state.
    */
-  kLcStateRma = 19 * 0x2108421,
-  /**
-   * SCRAP life cycle state where all functions are disabled.
-   */
-  kLcStateScrap = 20 * 0x2108421,
-  /**
-   * This state is temporary and behaves the same way as SCRAP.
-   */
-  kLcStatePostTransition = 21 * 0x2108421,
-  /**
-   * This state is temporary and behaves the same way as SCRAP.
-   */
-  kLcStateEscalate = 22 * 0x2108421,
-  /**
-   * This state is reported when the life cycle state encoding is invalid.
-   * This state is temporary and behaves the same way as SCRAP.
-   */
-  kLcStateInvalid = 23 * 0x2108421,
-  /**
-   * This is not a state - it is the total number of states.
-   */
-  kLcStateNumStates = 24,
+  kLcStateRma = 0xcf8cfaab,
 } lifecycle_state_t;
 
 enum {
@@ -136,17 +106,21 @@
 /**
  * Get the life cycle state.
  *
+ * This function checks the value read from the hardware and returns a
+ * `life_cycle_state_t`. See `life_cyle_state_t` for more details.
+ *
  * @return Life cycle state.
  */
 lifecycle_state_t lifecycle_state_get(void);
 
 /**
- * Get the human-readable name for a life cycle state.
+ * Get the unprocessed life cycle state value read from the hardware.
  *
- * @param lc_state Life cycle state.
- * @return Name of the given state.
+ * This function directly returns the `uint32_t` value read from the hardware.
+ *
+ * @return Life cycle state.
  */
-const char *lifecycle_state_name_get(lifecycle_state_t lc_state);
+uint32_t lifecycle_raw_state_get(void);
 
 /**
  * Get the device identifier.
diff --git a/sw/device/silicon_creator/lib/drivers/mock_lifecycle.h b/sw/device/silicon_creator/lib/drivers/mock_lifecycle.h
index fca4782..b1ced9a 100644
--- a/sw/device/silicon_creator/lib/drivers/mock_lifecycle.h
+++ b/sw/device/silicon_creator/lib/drivers/mock_lifecycle.h
@@ -17,6 +17,7 @@
 class MockLifecycle : public GlobalMock<MockLifecycle> {
  public:
   MOCK_METHOD(lifecycle_state_t, State, ());
+  MOCK_METHOD(uint32_t, RawState, ());
   MOCK_METHOD(void, DeviceId, (lifecycle_device_id_t * device_id));
 };
 
@@ -30,6 +31,10 @@
   return MockLifecycle::Instance().State();
 }
 
+uint32_t lifecycle_raw_state_get(void) {
+  return MockLifecycle::Instance().RawState();
+}
+
 void lifecycle_device_id_get(lifecycle_device_id_t *device_id) {
   MockLifecycle::Instance().DeviceId(device_id);
 }
diff --git a/sw/device/silicon_creator/lib/shutdown.c b/sw/device/silicon_creator/lib/shutdown.c
index 5c9274e..fa24236 100644
--- a/sw/device/silicon_creator/lib/shutdown.c
+++ b/sw/device/silicon_creator/lib/shutdown.c
@@ -71,14 +71,7 @@
   // Are we in a lifecycle state which needs alert configuration?
   uint32_t lc_shift;
   switch (lc_state) {
-    case kLcStateTestUnlocked0:
-    case kLcStateTestUnlocked1:
-    case kLcStateTestUnlocked2:
-    case kLcStateTestUnlocked3:
-    case kLcStateTestUnlocked4:
-    case kLcStateTestUnlocked5:
-    case kLcStateTestUnlocked6:
-    case kLcStateTestUnlocked7:
+    case kLcStateTest:
       // Don't configure alerts during manufacturing as OTP may not have been
       // programmed yet.
       return kErrorOk;
@@ -226,25 +219,25 @@
   //
   // Note that we cannot use the lifecycle or OTP libraries since an error
   // may trigger a call to `shutdown_finalize`.
-  lifecycle_state_t lc_state = (lifecycle_state_t)bitfield_field32_read(
-      abs_mmio_read32(TOP_EARLGREY_LC_CTRL_BASE_ADDR +
-                      LC_CTRL_LC_STATE_REG_OFFSET),
-      LC_CTRL_LC_STATE_STATE_FIELD);
-  switch (lc_state) {
-    case kLcStateTestUnlocked0:
-    case kLcStateTestUnlocked1:
-    case kLcStateTestUnlocked2:
-    case kLcStateTestUnlocked3:
-    case kLcStateTestUnlocked4:
-    case kLcStateTestUnlocked5:
-    case kLcStateTestUnlocked6:
-    case kLcStateTestUnlocked7:
-    case kLcStateRma:
+  uint32_t raw_state =
+      bitfield_field32_read(abs_mmio_read32(TOP_EARLGREY_LC_CTRL_BASE_ADDR +
+                                            LC_CTRL_LC_STATE_REG_OFFSET),
+                            LC_CTRL_LC_STATE_STATE_FIELD);
+  switch (raw_state) {
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0:
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1:
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2:
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3:
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4:
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5:
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6:
+    case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7:
+    case LC_CTRL_LC_STATE_STATE_VALUE_RMA:
       // No error redaction in TEST_UNLOCKED and RMA states.
       return kShutdownErrorRedactNone;
-    case kLcStateProd:
-    case kLcStateProdEnd:
-    case kLcStateDev:
+    case LC_CTRL_LC_STATE_STATE_VALUE_DEV:
+    case LC_CTRL_LC_STATE_STATE_VALUE_PROD:
+    case LC_CTRL_LC_STATE_STATE_VALUE_PROD_END:
       // In production states use the redaction level specified in OTP.
       return (shutdown_error_redact_t)abs_mmio_read32(
           TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR +
diff --git a/sw/device/silicon_creator/lib/shutdown_unittest.cc b/sw/device/silicon_creator/lib/shutdown_unittest.cc
index 7068993..288ffb0 100644
--- a/sw/device/silicon_creator/lib/shutdown_unittest.cc
+++ b/sw/device/silicon_creator/lib/shutdown_unittest.cc
@@ -505,10 +505,17 @@
 TEST_F(ShutdownTest, RedactPolicyManufacturing) {
   // Devices in manufacturing or RMA states should not redact errors regardless
   // of the redaction level set by OTP.
-  constexpr std::array<lifecycle_state_t, 9> kManufacturingStates = {
-      kLcStateTestUnlocked0, kLcStateTestUnlocked1, kLcStateTestUnlocked2,
-      kLcStateTestUnlocked3, kLcStateTestUnlocked4, kLcStateTestUnlocked5,
-      kLcStateTestUnlocked6, kLcStateTestUnlocked7, kLcStateRma};
+  constexpr std::array<uint32_t, 9> kManufacturingStates = {
+      LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0,
+      LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1,
+      LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2,
+      LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3,
+      LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4,
+      LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5,
+      LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6,
+      LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7,
+      LC_CTRL_LC_STATE_STATE_VALUE_RMA,
+  };
   for (const auto state : kManufacturingStates) {
     EXPECT_ABS_READ32(
         TOP_EARLGREY_LC_CTRL_BASE_ADDR + LC_CTRL_LC_STATE_REG_OFFSET,
@@ -519,8 +526,11 @@
 
 TEST_F(ShutdownTest, RedactPolicyProduction) {
   // Production states should read redaction level from OTP.
-  constexpr std::array<lifecycle_state_t, 3> kProductionStates = {
-      kLcStateProd, kLcStateProdEnd, kLcStateDev};
+  constexpr std::array<uint32_t, 3> kProductionStates = {
+      LC_CTRL_LC_STATE_STATE_VALUE_DEV,
+      LC_CTRL_LC_STATE_STATE_VALUE_PROD,
+      LC_CTRL_LC_STATE_STATE_VALUE_PROD_END,
+  };
   for (const auto state : kProductionStates) {
     EXPECT_ABS_READ32(
         TOP_EARLGREY_LC_CTRL_BASE_ADDR + LC_CTRL_LC_STATE_REG_OFFSET,
@@ -536,51 +546,25 @@
 TEST_F(ShutdownTest, RedactPolicyInvalid) {
   // Invalid states should result in the highest redaction level regardless of
   // the redaction level set by OTP.
-  constexpr std::array<lifecycle_state_t, 11> kInvalidStates = {
-      kLcStateTestLocked0, kLcStateTestLocked1, kLcStateTestLocked2,
-      kLcStateTestLocked3, kLcStateTestLocked4, kLcStateTestLocked5,
-      kLcStateTestLocked6, kLcStateScrap,       kLcStatePostTransition,
-      kLcStateEscalate,    kLcStateInvalid};
-  for (const auto state : kInvalidStates) {
-    EXPECT_ABS_READ32(
-        TOP_EARLGREY_LC_CTRL_BASE_ADDR + LC_CTRL_LC_STATE_REG_OFFSET,
-        static_cast<uint32_t>(state));
-    EXPECT_EQ(shutdown_redact_policy(), kShutdownErrorRedactAll);
-  }
+  EXPECT_ABS_READ32(
+      TOP_EARLGREY_LC_CTRL_BASE_ADDR + LC_CTRL_LC_STATE_REG_OFFSET, 0);
+  EXPECT_EQ(shutdown_redact_policy(), kShutdownErrorRedactAll);
 }
 
 TEST_F(ShutdownTest, InitializeManufacturing) {
   // OTP reads and alert setup should be skipped in the TEST_UNLOCKED lifecycle
   // states.
-  constexpr std::array<lifecycle_state_t, 8> kManufacturingStates = {
-      kLcStateTestUnlocked0, kLcStateTestUnlocked1, kLcStateTestUnlocked2,
-      kLcStateTestUnlocked3, kLcStateTestUnlocked4, kLcStateTestUnlocked5,
-      kLcStateTestUnlocked6, kLcStateTestUnlocked7,
-  };
-  for (auto state : kManufacturingStates) {
-    EXPECT_EQ(shutdown_init(state), kErrorOk);
-  }
+  EXPECT_EQ(shutdown_init(kLcStateTest), kErrorOk);
 }
 
 TEST_F(ShutdownTest, InitializeInvalid) {
-  // Invalid states (such as the INVALID lifecycle state itself) should be
-  // treated as PROD.
-  constexpr std::array<lifecycle_state_t, 12> kInvalidStates = {
-      kLcStateRaw,         kLcStateTestLocked0,
-      kLcStateTestLocked1, kLcStateTestLocked2,
-      kLcStateTestLocked3, kLcStateTestLocked4,
-      kLcStateTestLocked5, kLcStateTestLocked6,
-      kLcStateScrap,       kLcStatePostTransition,
-      kLcStateEscalate,    kLcStateInvalid,
-  };
-  for (auto state : kInvalidStates) {
-    SetupOtpReads();
-    ExpectFinalize(kErrorShutdownBadLcState);
+  SetupOtpReads();
+  ExpectFinalize(kErrorShutdownBadLcState);
 
-    // Note: the unmocked implementation of `shutdown_finalize` will never
-    // return and therefore `shutdown_init` will not return.
-    EXPECT_EQ(shutdown_init(state), kErrorShutdownBadLcState);
-  }
+  // Note: the unmocked implementation of `shutdown_finalize` will never
+  // return and therefore `shutdown_init` will not return.
+  EXPECT_EQ(shutdown_init(static_cast<lifecycle_state_t>(0)),
+            kErrorShutdownBadLcState);
 }
 
 TEST(ShutdownModule, RedactErrors) {
diff --git a/sw/device/silicon_creator/lib/sigverify.c b/sw/device/silicon_creator/lib/sigverify.c
index 9713f02..db22db0 100644
--- a/sw/device/silicon_creator/lib/sigverify.c
+++ b/sw/device/silicon_creator/lib/sigverify.c
@@ -207,14 +207,7 @@
 static rom_error_t sigverify_use_sw_rsa_verify(lifecycle_state_t lc_state,
                                                hardened_bool_t *use_sw) {
   switch (lc_state) {
-    case kLcStateTestUnlocked0:
-    case kLcStateTestUnlocked1:
-    case kLcStateTestUnlocked2:
-    case kLcStateTestUnlocked3:
-    case kLcStateTestUnlocked4:
-    case kLcStateTestUnlocked5:
-    case kLcStateTestUnlocked6:
-    case kLcStateTestUnlocked7:
+    case kLcStateTest:
       // Don't read from OTP during manufacturing. Use software
       // implementation by default.
       *use_sw = kHardenedBoolTrue;
diff --git a/sw/device/silicon_creator/lib/sigverify_unittest.cc b/sw/device/silicon_creator/lib/sigverify_unittest.cc
index 6600888..9adf452d 100644
--- a/sw/device/silicon_creator/lib/sigverify_unittest.cc
+++ b/sw/device/silicon_creator/lib/sigverify_unittest.cc
@@ -95,12 +95,6 @@
  * Life cycle states used in parameterized tests.
  */
 
-constexpr std::array<lifecycle_state_t, 8> kLcStatesTest{
-    kLcStateTestUnlocked0, kLcStateTestUnlocked1, kLcStateTestUnlocked2,
-    kLcStateTestUnlocked3, kLcStateTestUnlocked4, kLcStateTestUnlocked5,
-    kLcStateTestUnlocked6, kLcStateTestUnlocked7,
-};
-
 constexpr std::array<lifecycle_state_t, 4> kLcStatesNonTestOperational{
     kLcStateDev,
     kLcStateProd,
@@ -108,33 +102,6 @@
     kLcStateRma,
 };
 
-constexpr std::array<lifecycle_state_t, 12> kLcStatesNonOperational{
-    kLcStateRaw,         kLcStateTestLocked0,
-    kLcStateTestLocked1, kLcStateTestLocked2,
-    kLcStateTestLocked3, kLcStateTestLocked4,
-    kLcStateTestLocked5, kLcStateTestLocked6,
-    kLcStateScrap,       kLcStatePostTransition,
-    kLcStateEscalate,    kLcStateInvalid,
-};
-
-const std::unordered_set<lifecycle_state_t> &LcStatesAll() {
-  static const std::unordered_set<lifecycle_state_t> *const kLcStatesAll =
-      []() {
-        auto states = new std::unordered_set<lifecycle_state_t>();
-        states->insert(kLcStatesTest.begin(), kLcStatesTest.end());
-        states->insert(kLcStatesNonTestOperational.begin(),
-                       kLcStatesNonTestOperational.end());
-        states->insert(kLcStatesNonOperational.begin(),
-                       kLcStatesNonOperational.end());
-        return states;
-      }();
-  return *kLcStatesAll;
-}
-
-TEST(LcStateCount, IsCorrect) {
-  EXPECT_EQ(kLcStateNumStates, LcStatesAll().size());
-}
-
 class SigverifyInLcState
     : public mask_rom_test::MaskRomTest,
       public testing::WithParamInterface<lifecycle_state_t> {
@@ -223,18 +190,18 @@
 
 class SigverifyInTestStates : public SigverifyInLcState {};
 
-TEST_P(SigverifyInTestStates, GoodSignatureIbex) {
+TEST_F(SigverifyInTestStates, GoodSignatureIbex) {
   EXPECT_CALL(sigverify_mod_exp_ibex_, mod_exp(&key_, &kSignature, NotNull()))
       .WillOnce(DoAll(SetArgPointee<2>(kEncMsg), Return(kErrorOk)));
 
   uint32_t flash_exec = 0;
-  EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam(),
+  EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, kLcStateTest,
                                  &flash_exec),
             kErrorOk);
   EXPECT_EQ(flash_exec, kSigverifyFlashExec);
 }
 
-TEST_P(SigverifyInTestStates, BadSignatureIbex) {
+TEST_F(SigverifyInTestStates, BadSignatureIbex) {
   // Corrupt the words of the encoded message by flipping their bits and check
   // that signature verification fails.
   for (size_t i = 0; i < kSigVerifyRsaNumWords; ++i) {
@@ -245,29 +212,24 @@
         .WillOnce(DoAll(SetArgPointee<2>(bad_enc_msg), Return(kErrorOk)));
 
     uint32_t flash_exec = 0;
-    EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam(),
-                                   &flash_exec),
+    EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest,
+                                   kLcStateTest, &flash_exec),
               kErrorSigverifyBadEncodedMessage);
     EXPECT_EQ(flash_exec, std::numeric_limits<uint32_t>::max());
   }
 }
 
-INSTANTIATE_TEST_SUITE_P(TestStates, SigverifyInTestStates,
-                         testing::ValuesIn(kLcStatesTest));
-
 class SigverifyInInvalidStates : public SigverifyInLcState {};
 
-TEST_P(SigverifyInInvalidStates, BadLcState) {
+TEST_F(SigverifyInInvalidStates, BadLcState) {
   uint32_t flash_exec = 0;
-  EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam(),
-                                 &flash_exec),
-            kErrorSigverifyBadLcState);
+  EXPECT_EQ(
+      sigverify_rsa_verify(&kSignature, &key_, &kTestDigest,
+                           static_cast<lifecycle_state_t>(0), &flash_exec),
+      kErrorSigverifyBadLcState);
   EXPECT_EQ(flash_exec, std::numeric_limits<uint32_t>::max());
 }
 
-INSTANTIATE_TEST_SUITE_P(NonOperationalStates, SigverifyInInvalidStates,
-                         testing::ValuesIn(kLcStatesNonOperational));
-
 struct UsageConstraintsTestCase {
   uint32_t selector_bits;
   lifecycle_device_id_t exp_device_id;
diff --git a/sw/device/silicon_creator/mask_rom/mask_rom.c b/sw/device/silicon_creator/mask_rom/mask_rom.c
index bca705e..440a8d0 100644
--- a/sw/device/silicon_creator/mask_rom/mask_rom.c
+++ b/sw/device/silicon_creator/mask_rom/mask_rom.c
@@ -199,7 +199,7 @@
   // TODO(lowrisc/opentitan#7894): What (if anything) should we print at
   // startup?
   log_printf("OpenTitan: \"version-tag\"\r\n");
-  log_printf("lc_state: %s\r\n", lifecycle_state_name_get(lc_state));
+  log_printf("lc_state: 0x%x\r\n", (unsigned int)lifecycle_raw_state_get());
 
   // TODO(lowrisc/opentitan#1513): Switch to EEPROM SPI device bootstrap
   // protocol.
diff --git a/sw/device/silicon_creator/mask_rom/sigverify_keys.c b/sw/device/silicon_creator/mask_rom/sigverify_keys.c
index b604ee9..5df248e 100644
--- a/sw/device/silicon_creator/mask_rom/sigverify_keys.c
+++ b/sw/device/silicon_creator/mask_rom/sigverify_keys.c
@@ -185,29 +185,8 @@
 static rom_error_t key_is_valid(sigverify_key_type_t key_type,
                                 lifecycle_state_t lc_state, size_t key_index) {
   switch (launder32(lc_state)) {
-    case kLcStateTestUnlocked0:
-      HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked0);
-      return key_is_valid_in_lc_state_test(key_type);
-    case kLcStateTestUnlocked1:
-      HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked1);
-      return key_is_valid_in_lc_state_test(key_type);
-    case kLcStateTestUnlocked2:
-      HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked2);
-      return key_is_valid_in_lc_state_test(key_type);
-    case kLcStateTestUnlocked3:
-      HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked3);
-      return key_is_valid_in_lc_state_test(key_type);
-    case kLcStateTestUnlocked4:
-      HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked4);
-      return key_is_valid_in_lc_state_test(key_type);
-    case kLcStateTestUnlocked5:
-      HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked5);
-      return key_is_valid_in_lc_state_test(key_type);
-    case kLcStateTestUnlocked6:
-      HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked6);
-      return key_is_valid_in_lc_state_test(key_type);
-    case kLcStateTestUnlocked7:
-      HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked7);
+    case kLcStateTest:
+      HARDENED_CHECK_EQ(lc_state, kLcStateTest);
       return key_is_valid_in_lc_state_test(key_type);
     case kLcStateProd:
       HARDENED_CHECK_EQ(lc_state, kLcStateProd);
diff --git a/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc b/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
index d5fa82c..9493b80 100644
--- a/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
+++ b/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
@@ -82,12 +82,6 @@
  * Life cycle states used in parameterized tests.
  */
 
-constexpr std::array<lifecycle_state_t, 8> kLcStatesTest{
-    kLcStateTestUnlocked0, kLcStateTestUnlocked1, kLcStateTestUnlocked2,
-    kLcStateTestUnlocked3, kLcStateTestUnlocked4, kLcStateTestUnlocked5,
-    kLcStateTestUnlocked6, kLcStateTestUnlocked7,
-};
-
 constexpr std::array<lifecycle_state_t, 4> kLcStatesNonTestOperational{
     kLcStateDev,
     kLcStateProd,
@@ -95,33 +89,16 @@
     kLcStateRma,
 };
 
-constexpr std::array<lifecycle_state_t, 12> kLcStatesNonOperational{
-    kLcStateRaw,         kLcStateTestLocked0,
-    kLcStateTestLocked1, kLcStateTestLocked2,
-    kLcStateTestLocked3, kLcStateTestLocked4,
-    kLcStateTestLocked5, kLcStateTestLocked6,
-    kLcStateScrap,       kLcStatePostTransition,
-    kLcStateEscalate,    kLcStateInvalid,
+constexpr std::array<lifecycle_state_t, 6> kLcStatesAll{
+    kLcStateTest,
+    kLcStateDev,
+    kLcStateProd,
+    kLcStateProdEnd,
+    kLcStateRma,
+    // An invalid state
+    static_cast<lifecycle_state_t>(0),
 };
 
-const std::unordered_set<lifecycle_state_t> &LcStatesAll() {
-  static const std::unordered_set<lifecycle_state_t> *const kLcStatesAll =
-      []() {
-        auto states = new std::unordered_set<lifecycle_state_t>();
-        states->insert(kLcStatesTest.begin(), kLcStatesTest.end());
-        states->insert(kLcStatesNonTestOperational.begin(),
-                       kLcStatesNonTestOperational.end());
-        states->insert(kLcStatesNonOperational.begin(),
-                       kLcStatesNonOperational.end());
-        return states;
-      }();
-  return *kLcStatesAll;
-}
-
-TEST(LcStateCount, IsCorrect) {
-  EXPECT_EQ(kLcStateNumStates, LcStatesAll().size());
-}
-
 class SigverifyKeys : public mask_rom_test::MaskRomTest {
  protected:
   /**
@@ -180,7 +157,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(AllLcStates, BadKeyIdTypeTest,
-                         testing::ValuesIn(LcStatesAll()));
+                         testing::ValuesIn(kLcStatesAll));
 
 class BadKeyIdTypeDeathTest : public BadKeyIdTypeTest {};
 
@@ -205,7 +182,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(AllLcStates, BadKeyIdTypeDeathTest,
-                         testing::ValuesIn(LcStatesAll()));
+                         testing::ValuesIn(kLcStatesAll));
 
 /**
  * Base class for paramaterized tests below.
@@ -235,7 +212,7 @@
 INSTANTIATE_TEST_SUITE_P(
     AllKeysAndNonOperationalStates, NonOperationalStateDeathTest,
     testing::Combine(testing::Range<size_t>(0, kNumMockKeys),
-                     testing::ValuesIn(kLcStatesNonOperational)));
+                     testing::Values(static_cast<lifecycle_state_t>(0))));
 
 class ValidBasedOnOtp : public KeyValidityTest {};
 
@@ -310,13 +287,13 @@
     ProdKeysInTestStates, ValidInState,
     testing::Combine(
         testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeProd)),
-        testing::ValuesIn(kLcStatesTest)));
+        testing::Values(kLcStateTest)));
 
 INSTANTIATE_TEST_SUITE_P(
     TestKeysInTestStates, ValidInState,
     testing::Combine(
         testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeTest)),
-        testing::ValuesIn(kLcStatesTest)));
+        testing::Values(kLcStateTest)));
 
 class InvalidInState : public KeyValidityTest {};
 
@@ -344,7 +321,7 @@
     DevKeysAndTestStates, InvalidInState,
     testing::Combine(
         testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeDev)),
-        testing::ValuesIn(kLcStatesTest)));
+        testing::Values(kLcStateTest)));
 
 INSTANTIATE_TEST_SUITE_P(
     DevKeysAndNonDevOperStates, InvalidInState,