[sw/silicon_creator] Harden flash_ctrl_info_page_enum_t

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/drivers/BUILD b/sw/device/silicon_creator/lib/drivers/BUILD
index 6ee00e4..3bf7027 100644
--- a/sw/device/silicon_creator/lib/drivers/BUILD
+++ b/sw/device/silicon_creator/lib/drivers/BUILD
@@ -63,6 +63,7 @@
     name = "flash_ctrl",
     srcs = ["flash_ctrl.c"],
     hdrs = ["flash_ctrl.h"],
+    target_compatible_with = [OPENTITAN_CPU],
     deps = [
         "//hw/ip/flash_ctrl/data:flash_ctrl_regs",
         "//hw/ip/otp_ctrl/data:otp_ctrl_regs",
@@ -77,9 +78,15 @@
 
 cc_test(
     name = "flash_ctrl_unittest",
-    srcs = ["flash_ctrl_unittest.cc"],
+    srcs = [
+        "flash_ctrl.h",
+        "flash_ctrl.c",
+        "flash_ctrl_unittest.cc",
+    ],
+    defines = [
+        "OT_OFF_TARGET_TEST",
+    ],
     deps = [
-        ":flash_ctrl",
         "//hw/ip/flash_ctrl/data:flash_ctrl_regs",
         "//hw/ip/otp_ctrl/data:otp_ctrl_regs",
         "//sw/device/lib/base",
diff --git a/sw/device/silicon_creator/lib/drivers/flash_ctrl.c b/sw/device/silicon_creator/lib/drivers/flash_ctrl.c
index 23ffdb2..4988025 100644
--- a/sw/device/silicon_creator/lib/drivers/flash_ctrl.c
+++ b/sw/device/silicon_creator/lib/drivers/flash_ctrl.c
@@ -208,12 +208,19 @@
  * @return Base address of the given page.
  */
 static uint32_t info_page_addr(flash_ctrl_info_page_t info_page) {
-  const uint32_t bank_index =
-      bitfield_bit32_read(info_page, FLASH_CTRL_INFO_PAGE_BIT_BANK);
-  const uint32_t page_index =
-      bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PAGE);
-  return kMemBase + bank_index * FLASH_CTRL_PARAM_BYTES_PER_BANK +
-         page_index * FLASH_CTRL_PARAM_BYTES_PER_PAGE;
+#define INFO_PAGE_ADDR_CASE_(name_, value_, bank_, page_)       \
+  case (name_):                                                 \
+    SHUTDOWN_CHECK(launder32(info_page) == (name_));            \
+    return kMemBase + (bank_)*FLASH_CTRL_PARAM_BYTES_PER_BANK + \
+           (page_)*FLASH_CTRL_PARAM_BYTES_PER_PAGE;
+
+  switch (launder32(info_page)) {
+    FLASH_CTRL_INFO_PAGES_DEFINE(INFO_PAGE_ADDR_CASE_)
+    default:
+      SHUTDOWN_CHECK(false);
+  }
+
+#undef INFO_PAGE_ADDR_CASE_
 }
 
 /**
@@ -240,28 +247,25 @@
  * @return Config and config write-enable register addresses of the info page.
  */
 static info_cfg_regs_t info_cfg_regs(flash_ctrl_info_page_t info_page) {
-  // For each bank and info page type, there are N config regwen registers
-  // followed by N config registers, where N is the number pages available for
-  // the info page type. These "blocks" of registers are mapped to a contiguous
-  // address space by bank number starting with config regwen registers for page
-  // 0-9, type 0, bank 0, followed by config registers for page 0-9, type 0,
-  // bank 0, and so on.
-  enum {
-    kBankOffset = FLASH_CTRL_BANK1_INFO0_PAGE_CFG_SHADOWED_0_REG_OFFSET -
-                  FLASH_CTRL_BANK0_INFO0_PAGE_CFG_SHADOWED_0_REG_OFFSET,
-    kPageOffset = sizeof(uint32_t),
-  };
-  const uint32_t bank_index =
-      bitfield_bit32_read(info_page, FLASH_CTRL_INFO_PAGE_BIT_BANK);
-  const uint32_t page_index =
-      bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PAGE);
-  const uint32_t pre_addr =
-      kBase + bank_index * kBankOffset + page_index * kPageOffset;
-  return (info_cfg_regs_t){
-      .cfg_wen_addr = pre_addr + FLASH_CTRL_BANK0_INFO0_REGWEN_0_REG_OFFSET,
-      .cfg_addr =
-          pre_addr + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_SHADOWED_0_REG_OFFSET,
-  };
+#define INFO_CFG_REGS_CASE_(name_, value_, bank_, page_)                           \
+  case (name_):                                                                    \
+    SHUTDOWN_CHECK(launder32(info_page) == (name_));                               \
+    return (info_cfg_regs_t){                                                      \
+        .cfg_wen_addr =                                                            \
+            kBase +                                                                \
+            FLASH_CTRL_BANK##bank_##_INFO0_REGWEN_##page_##_REG_OFFSET,            \
+        .cfg_addr =                                                                \
+            kBase +                                                                \
+            FLASH_CTRL_BANK##bank_##_INFO0_PAGE_CFG_SHADOWED_##page_##_REG_OFFSET, \
+    };
+
+  switch (launder32(info_page)) {
+    FLASH_CTRL_INFO_PAGES_DEFINE(INFO_CFG_REGS_CASE_)
+    default:
+      SHUTDOWN_CHECK(false);
+  }
+
+#undef INFO_CFG_REGS_CASE_
 }
 
 /**
@@ -343,12 +347,10 @@
                                  uint32_t offset, uint32_t word_count,
                                  uint32_t *data) {
   const uint32_t addr = info_page_addr(info_page) + offset;
-  const flash_ctrl_partition_t partition =
-      bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PARTITION);
   transaction_start((transaction_params_t){
       .addr = addr,
       .op_type = FLASH_CTRL_CONTROL_OP_VALUE_READ,
-      .partition = partition,
+      .partition = kFlashCtrlPartitionInfo0,
       .word_count = word_count,
       // Does not apply to read transactions.
       .erase_type = kFlashCtrlEraseTypePage,
@@ -367,9 +369,8 @@
                                   uint32_t offset, uint32_t word_count,
                                   const uint32_t *data) {
   const uint32_t addr = info_page_addr(info_page) + offset;
-  const flash_ctrl_partition_t partition =
-      bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PARTITION);
-  return write(addr, partition, word_count, data, kErrorFlashCtrlInfoWrite);
+  return write(addr, kFlashCtrlPartitionInfo0, word_count, data,
+               kErrorFlashCtrlInfoWrite);
 }
 
 rom_error_t flash_ctrl_data_erase(uint32_t addr,
@@ -388,13 +389,11 @@
 rom_error_t flash_ctrl_info_erase(flash_ctrl_info_page_t info_page,
                                   flash_ctrl_erase_type_t erase_type) {
   const uint32_t addr = info_page_addr(info_page);
-  const flash_ctrl_partition_t partition =
-      bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PARTITION);
   transaction_start((transaction_params_t){
       .addr = addr,
       .op_type = FLASH_CTRL_CONTROL_OP_VALUE_ERASE,
       .erase_type = erase_type,
-      .partition = partition,
+      .partition = kFlashCtrlPartitionInfo0,
       // Does not apply to erase transactions.
       .word_count = 1,
   });
diff --git a/sw/device/silicon_creator/lib/drivers/flash_ctrl.h b/sw/device/silicon_creator/lib/drivers/flash_ctrl.h
index f6e3f33..1330883 100644
--- a/sw/device/silicon_creator/lib/drivers/flash_ctrl.h
+++ b/sw/device/silicon_creator/lib/drivers/flash_ctrl.h
@@ -57,60 +57,97 @@
   ((bitfield_field32_t){.mask = 0x3, .index = 1})
 
 /**
- * Helper macro for defining the value of a `flash_ctrl_info_page_t` enumeration
- * constant for information pages of type 0.
+ * Table of flash information pages.
  *
- * Each `flash_ctrl_info_page_t` enumeration constant is a bitfield with the
- * following layout:
- * - Bits 0-3: Page index ([0,9] for type 0, 0 for type 1, [0,1] for type 2).
- * - Bits 4-6: Partition type (a `flash_ctrl_partition_type_t`).
- * - Bit 7: Bank index [0,1].
+ * Columns: Name, value, bank index, page index.
+ * We use an X macro to faciliate writing enums, swtich statements, and unit
+ * tests using the contants here. All information pages in this table are of
+ * type 0 since silicon creator code does not need to access information pages
+ * of other types.
  *
- * This macro assumes that all information pages are of type 0 since silicon
- * creator code does not need to access information pages of other types.
+ * Encoding generated with
+ * $ ./util/design/sparse-fsm-encode.py -d 6 -m 20 -n 32 \
+ *     -s 1755363476 --language=c
  *
- * @param bank_ Bank index.
- * @param page_ Page index.
+ * Hamming distance histogram:
+ *
+ *  0: --
+ *  1: --
+ *  2: --
+ *  3: --
+ *  4: --
+ *  5: --
+ *  6: --
+ *  7: --
+ *  8: --
+ *  9:  (0.53%)
+ * 10: || (2.63%)
+ * 11: || (2.11%)
+ * 12: |||||| (6.84%)
+ * 13: |||||| (6.84%)
+ * 14: ||||||||||| (12.11%)
+ * 15: ||||||||||| (11.58%)
+ * 16: |||||||||||||||||||| (20.53%)
+ * 17: ||||||||| (10.00%)
+ * 18: |||||||||| (10.53%)
+ * 19: ||||||| (7.37%)
+ * 20: |||||| (6.84%)
+ * 21: | (1.05%)
+ * 22: | (1.05%)
+ * 23: --
+ * 24: --
+ * 25: --
+ * 26: --
+ * 27: --
+ * 28: --
+ * 29: --
+ * 30: --
+ * 31: --
+ * 32: --
+ *
+ * Minimum Hamming distance: 9
+ * Maximum Hamming distance: 22
+ * Minimum Hamming weight: 13
+ * Maximum Hamming weight: 25
  */
-#define INFO_PAGE_(bank_, page_) \
-  ((bank_ << 7) | (kFlashCtrlPartitionInfo0 << 4) | (page_))
-
 // clang-format off
 #define FLASH_CTRL_INFO_PAGES_DEFINE(X) \
   /**
    * Bank 0 information partition type 0 pages.
    */ \
-  X(kFlashCtrlInfoPageFactoryId,          0, 0), \
-  X(kFlashCtrlInfoPageCreatorSecret,      0, 1), \
-  X(kFlashCtrlInfoPageOwnerSecret,        0, 2), \
-  X(kFlashCtrlInfoPageWaferAuthSecret,    0, 3), \
-  X(kFlashCtrlInfoPageBank0Type0Page4,    0, 4), \
-  X(kFlashCtrlInfoPageBank0Type0Page5,    0, 5), \
-  X(kFlashCtrlInfoPageOwnerReserved0,     0, 6), \
-  X(kFlashCtrlInfoPageOwnerReserved1,     0, 7), \
-  X(kFlashCtrlInfoPageOwnerReserved2,     0, 8), \
-  X(kFlashCtrlInfoPageOwnerReserved3,     0, 9), \
+  X(kFlashCtrlInfoPageFactoryId,         	0x9dc41c33, 0, 0) \
+  X(kFlashCtrlInfoPageCreatorSecret,     	0xf56af4bb, 0, 1) \
+  X(kFlashCtrlInfoPageOwnerSecret,       	0x10adc6aa, 0, 2) \
+  X(kFlashCtrlInfoPageWaferAuthSecret,   	0x118b5dbb, 0, 3) \
+  X(kFlashCtrlInfoPageBank0Type0Page4,   	0xad3b5bee, 0, 4) \
+  X(kFlashCtrlInfoPageBank0Type0Page5,   	0xa4f6f6c3, 0, 5) \
+  X(kFlashCtrlInfoPageOwnerReserved0,    	0xf646f11b, 0, 6) \
+  X(kFlashCtrlInfoPageOwnerReserved1,    	0x6c86d980, 0, 7) \
+  X(kFlashCtrlInfoPageOwnerReserved2,    	0xdd7f34dc, 0, 8) \
+  X(kFlashCtrlInfoPageOwnerReserved3,    	0x5f07277e, 0, 9) \
   /**
    * Bank 1 information partition type 0 pages.
    */ \
-  X(kFlashCtrlInfoPageBootData0,          1, 0), \
-  X(kFlashCtrlInfoPageBootData1,          1, 1), \
-  X(kFlashCtrlInfoPageOwnerSlot0,         1, 2), \
-  X(kFlashCtrlInfoPageOwnerSlot1,         1, 3), \
-  X(kFlashCtrlInfoPageBank1Type0Page4,    1, 4), \
-  X(kFlashCtrlInfoPageBank1Type0Page5,    1, 5), \
-  X(kFlashCtrlInfoPageCreatorCertificate, 1, 6), \
-  X(kFlashCtrlInfoPageBootServices,       1, 7), \
-  X(kFlashCtrlInfoPageOwnerCerificate0,   1, 8), \
-  X(kFlashCtrlInfoPageOwnerCerificate1,   1, 9), \
+  X(kFlashCtrlInfoPageBootData0,          0xfa38c9f6, 1, 0) \
+  X(kFlashCtrlInfoPageBootData1,          0x389c449e, 1, 1) \
+  X(kFlashCtrlInfoPageOwnerSlot0,         0x238cf15c, 1, 2) \
+  X(kFlashCtrlInfoPageOwnerSlot1,         0xad886d3b, 1, 3) \
+  X(kFlashCtrlInfoPageBank1Type0Page4,    0x7dfbdf9b, 1, 4) \
+  X(kFlashCtrlInfoPageBank1Type0Page5,    0xad5dd31d, 1, 5) \
+  X(kFlashCtrlInfoPageCreatorCertificate, 0xe3ffac86, 1, 6) \
+  X(kFlashCtrlInfoPageBootServices,       0xf4f48c3d, 1, 7) \
+  X(kFlashCtrlInfoPageOwnerCerificate0,   0x9fbb840e, 1, 8) \
+  X(kFlashCtrlInfoPageOwnerCerificate1,   0xec309461, 1, 9) \
 // clang-format on
 
 /**
  * Helper macro for defining a `flash_ctrl_info_page_t` enumeration constant.
- * @name_ Name of the enumeration constant.
- * @value_ Value of the enumeration constant.
+ * @param name_ Name of the enumeration constant.
+ * @param value_ Value of the enumeration constant.
+ * @param bank_ Bank of the info page.
+ * @param page_ Page of the info page.
  */
-#define INFO_PAGE_ENUM_INIT_(name_, bank_, page_) name_ = INFO_PAGE_(bank_, page_)
+#define INFO_PAGE_ENUM_INIT_(name_, value_, bank_, page_) name_ = value_,
 
 /**
  * Info pages.
@@ -120,16 +157,6 @@
 } flash_ctrl_info_page_t;
 
 /**
- * Field and bit definitions to get page index, partition type, and bank index
- * from a `flash_ctrl_info_page_t`.
- */
-#define FLASH_CTRL_INFO_PAGE_FIELD_PAGE \
-  ((bitfield_field32_t){.mask = 0xf, .index = 0})
-#define FLASH_CTRL_INFO_PAGE_FIELD_PARTITION \
-  ((bitfield_field32_t){.mask = 0x7, .index = 4})
-#define FLASH_CTRL_INFO_PAGE_BIT_BANK 7
-
-/**
  * Bitfields for `CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG` and
  * `CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG` OTP items.
  *
diff --git a/sw/device/silicon_creator/lib/drivers/flash_ctrl_unittest.cc b/sw/device/silicon_creator/lib/drivers/flash_ctrl_unittest.cc
index 3a4ed1c..c29ed28 100644
--- a/sw/device/silicon_creator/lib/drivers/flash_ctrl_unittest.cc
+++ b/sw/device/silicon_creator/lib/drivers/flash_ctrl_unittest.cc
@@ -38,16 +38,16 @@
  * tests.
  */
 const std::map<flash_ctrl_info_page_t, InfoPage> &InfoPages() {
-#define INFO_PAGE_MAP_INIT(name_, bank_, page_)                                    \
-  {                                                                                \
-    name_,                                                                         \
-        {                                                                          \
-            bank_,                                                                 \
-            page_,                                                                 \
-            FLASH_CTRL_BANK##bank_##_INFO0_PAGE_CFG_SHADOWED_##page_##_REG_OFFSET, \
-            FLASH_CTRL_BANK##bank_##_INFO0_REGWEN_##page_##_REG_OFFSET,            \
-        },                                                                         \
-  }
+#define INFO_PAGE_MAP_INIT(name_, value_, bank_, page_)                          \
+  {                                                                              \
+      name_,                                                                     \
+      {                                                                          \
+          bank_,                                                                 \
+          page_,                                                                 \
+          FLASH_CTRL_BANK##bank_##_INFO0_PAGE_CFG_SHADOWED_##page_##_REG_OFFSET, \
+          FLASH_CTRL_BANK##bank_##_INFO0_REGWEN_##page_##_REG_OFFSET,            \
+      },                                                                         \
+  },
 
   static const std::map<flash_ctrl_info_page_t, InfoPage> *const kInfoPages =
       new std::map<flash_ctrl_info_page_t, InfoPage>{
@@ -70,8 +70,6 @@
   std::array<uint32_t, 2> pages_per_bank = {0, 0};
   for (const auto &it : InfoPages()) {
     const uint32_t bank = it.second.bank;
-    EXPECT_EQ(bank, static_cast<uint32_t>(bitfield_bit32_read(
-                        it.first, FLASH_CTRL_INFO_PAGE_BIT_BANK)));
     EXPECT_LE(bank, 1);
     ++pages_per_bank[bank];
   }
@@ -79,21 +77,9 @@
   EXPECT_THAT(pages_per_bank, Each(10));
 }
 
-TEST_F(InfoPagesTest, AllType0) {
-  for (const auto &it : InfoPages()) {
-    const flash_ctrl_partition_t partition =
-        static_cast<flash_ctrl_partition_t>(bitfield_field32_read(
-            it.first, FLASH_CTRL_INFO_PAGE_FIELD_PARTITION));
-    EXPECT_EQ(partition, kFlashCtrlPartitionInfo0);
-  }
-}
-
 TEST_F(InfoPagesTest, PageIndices) {
   for (const auto &it : InfoPages()) {
     const uint32_t page = it.second.page;
-
-    EXPECT_EQ(page,
-              bitfield_field32_read(it.first, FLASH_CTRL_INFO_PAGE_FIELD_PAGE));
     EXPECT_LE(page, 9);
   }
 }
diff --git a/sw/device/silicon_creator/lib/drivers/meson.build b/sw/device/silicon_creator/lib/drivers/meson.build
index 06a1188..26bed06 100644
--- a/sw/device/silicon_creator/lib/drivers/meson.build
+++ b/sw/device/silicon_creator/lib/drivers/meson.build
@@ -520,6 +520,7 @@
       sw_silicon_creator_lib_base_abs_mmio,
       sw_silicon_creator_lib_base_sec_mmio,
       sw_silicon_creator_lib_driver_otp,
+      sw_lib_hardened,
     ],
   ),
 )
@@ -536,10 +537,11 @@
       sw_vendor_gtest,
       sw_silicon_creator_lib_base_mock_abs_mmio,
       sw_silicon_creator_lib_base_mock_sec_mmio,
+      sw_lib_testing_hardened,
     ],
     native: true,
-    c_args: ['-DMOCK_ABS_MMIO', '-DMOCK_SEC_MMIO'],
-    cpp_args: ['-DMOCK_ABS_MMIO', '-DMOCK_SEC_MMIO'],
+    c_args: ['-DMOCK_ABS_MMIO', '-DMOCK_SEC_MMIO', '-DOT_OFF_TARGET_TEST'],
+    cpp_args: ['-DMOCK_ABS_MMIO', '-DMOCK_SEC_MMIO', '-DOT_OFF_TARGET_TEST'],
   ),
   suite: 'mask_rom',
 )