[mask_rom] HMAC driver fixes for digest reading and endianness

This change fixes `hmac_sha256_init` and `hmac_sha256_final` to match
the output of `openssl` and `sha256sum` and preserve the numerical value
of the digest.

It also fixes IRQ clearing in these functions so that the driver can be
used more than once. This is required to be able to verify the second
slot if the first one does not succeed.

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/drivers/hmac.c b/sw/device/silicon_creator/lib/drivers/hmac.c
index b60c994..106bb8c 100644
--- a/sw/device/silicon_creator/lib/drivers/hmac.c
+++ b/sw/device/silicon_creator/lib/drivers/hmac.c
@@ -19,13 +19,14 @@
   // Clear the config, stopping the SHA engine.
   mmio_region_write32(hmac->base_addr, HMAC_CFG_REG_OFFSET, 0u);
 
-  // Disable and clear interrupts
+  // Disable and clear interrupts. INTR_STATE register is rw1c.
   mmio_region_write32(hmac->base_addr, HMAC_INTR_ENABLE_REG_OFFSET, 0u);
-  mmio_region_write32(hmac->base_addr, HMAC_INTR_STATE_REG_OFFSET, 0u);
+  mmio_region_write32(hmac->base_addr, HMAC_INTR_STATE_REG_OFFSET, UINT32_MAX);
 
   uint32_t reg = 0;
   reg = bitfield_bit32_write(reg, HMAC_CFG_DIGEST_SWAP_BIT, false);
-  reg = bitfield_bit32_write(reg, HMAC_CFG_ENDIAN_SWAP_BIT, false);
+  // Enable endian swap since our inputs are little-endian.
+  reg = bitfield_bit32_write(reg, HMAC_CFG_ENDIAN_SWAP_BIT, true);
   reg = bitfield_bit32_write(reg, HMAC_CFG_SHA_EN_BIT, true);
   reg = bitfield_bit32_write(reg, HMAC_CFG_HMAC_EN_BIT, false);
   mmio_region_write32(hmac->base_addr, HMAC_CFG_REG_OFFSET, reg);
@@ -76,12 +77,14 @@
   do {
     reg = mmio_region_read32(hmac->base_addr, HMAC_INTR_STATE_REG_OFFSET);
   } while (!bitfield_bit32_read(reg, HMAC_INTR_STATE_HMAC_DONE_BIT));
-
-  reg = bitfield_bit32_write(reg, HMAC_INTR_STATE_HMAC_DONE_BIT, false);
   mmio_region_write32(hmac->base_addr, HMAC_INTR_STATE_REG_OFFSET, reg);
 
-  mmio_region_memcpy_from_mmio32(hmac->base_addr, HMAC_DIGEST_0_REG_OFFSET,
-                                 digest->digest,
-                                 HMAC_PARAM_NUMWORDS * sizeof(uint32_t));
+  // Read the digest in reverse to preserve the numerical value.
+  // The least significant word is at HMAC_DIGEST_7_REG_OFFSET.
+  for (size_t i = 0; i < ARRAYSIZE(digest->digest); ++i) {
+    digest->digest[i] = mmio_region_read32(
+        hmac->base_addr, HMAC_DIGEST_7_REG_OFFSET - (i * sizeof(uint32_t)));
+  }
+
   return kErrorOk;
 }
diff --git a/sw/device/silicon_creator/lib/drivers/hmac_unittest.cc b/sw/device/silicon_creator/lib/drivers/hmac_unittest.cc
index 91b4a7b..8e22f9e 100644
--- a/sw/device/silicon_creator/lib/drivers/hmac_unittest.cc
+++ b/sw/device/silicon_creator/lib/drivers/hmac_unittest.cc
@@ -5,7 +5,7 @@
 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
 
 #include <array>
-#include <vector>
+#include <limits>
 
 #include "gtest/gtest.h"
 #include "sw/device/lib/base/mmio.h"
@@ -17,10 +17,7 @@
 namespace hmac_unittest {
 namespace {
 using ::mock_mmio::MmioTest;
-using ::mock_mmio::MockDevice;
-using ::testing::Each;
 using ::testing::ElementsAreArray;
-using ::testing::Eq;
 using ::testing::Test;
 
 class HmacTest : public Test, public MmioTest {
@@ -37,10 +34,11 @@
 TEST_F(Sha256InitTest, Initialize) {
   EXPECT_WRITE32(HMAC_CFG_REG_OFFSET, 0u);
   EXPECT_WRITE32(HMAC_INTR_ENABLE_REG_OFFSET, 0u);
-  EXPECT_WRITE32(HMAC_INTR_STATE_REG_OFFSET, 0u);
+  EXPECT_WRITE32(HMAC_INTR_STATE_REG_OFFSET,
+                 std::numeric_limits<uint32_t>::max());
   EXPECT_WRITE32(HMAC_CFG_REG_OFFSET, {
                                           {HMAC_CFG_DIGEST_SWAP_BIT, false},
-                                          {HMAC_CFG_ENDIAN_SWAP_BIT, false},
+                                          {HMAC_CFG_ENDIAN_SWAP_BIT, true},
                                           {HMAC_CFG_SHA_EN_BIT, true},
                                           {HMAC_CFG_HMAC_EN_BIT, false},
                                       });
@@ -111,19 +109,19 @@
                 });
   EXPECT_WRITE32(HMAC_INTR_STATE_REG_OFFSET,
                  {
-                     {HMAC_INTR_STATE_HMAC_DONE_BIT, false},
+                     {HMAC_INTR_STATE_HMAC_DONE_BIT, true},
                  });
 
   // Set expectations explicitly to ensure that the registers
   // are contiguous.
-  EXPECT_READ32(HMAC_DIGEST_0_REG_OFFSET, kExpectedDigest[0]);
-  EXPECT_READ32(HMAC_DIGEST_1_REG_OFFSET, kExpectedDigest[1]);
-  EXPECT_READ32(HMAC_DIGEST_2_REG_OFFSET, kExpectedDigest[2]);
-  EXPECT_READ32(HMAC_DIGEST_3_REG_OFFSET, kExpectedDigest[3]);
-  EXPECT_READ32(HMAC_DIGEST_4_REG_OFFSET, kExpectedDigest[4]);
-  EXPECT_READ32(HMAC_DIGEST_5_REG_OFFSET, kExpectedDigest[5]);
-  EXPECT_READ32(HMAC_DIGEST_6_REG_OFFSET, kExpectedDigest[6]);
-  EXPECT_READ32(HMAC_DIGEST_7_REG_OFFSET, kExpectedDigest[7]);
+  EXPECT_READ32(HMAC_DIGEST_7_REG_OFFSET, kExpectedDigest[0]);
+  EXPECT_READ32(HMAC_DIGEST_6_REG_OFFSET, kExpectedDigest[1]);
+  EXPECT_READ32(HMAC_DIGEST_5_REG_OFFSET, kExpectedDigest[2]);
+  EXPECT_READ32(HMAC_DIGEST_4_REG_OFFSET, kExpectedDigest[3]);
+  EXPECT_READ32(HMAC_DIGEST_3_REG_OFFSET, kExpectedDigest[4]);
+  EXPECT_READ32(HMAC_DIGEST_2_REG_OFFSET, kExpectedDigest[5]);
+  EXPECT_READ32(HMAC_DIGEST_1_REG_OFFSET, kExpectedDigest[6]);
+  EXPECT_READ32(HMAC_DIGEST_0_REG_OFFSET, kExpectedDigest[7]);
 
   hmac_digest_t got_digest;
   EXPECT_EQ(hmac_sha256_final(&hmac_, &got_digest), kErrorOk);
diff --git a/sw/device/silicon_creator/mask_rom/mask_rom.c b/sw/device/silicon_creator/mask_rom/mask_rom.c
index 77d7b42..ac475dd 100644
--- a/sw/device/silicon_creator/mask_rom/mask_rom.c
+++ b/sw/device/silicon_creator/mask_rom/mask_rom.c
@@ -24,9 +24,10 @@
 static const uint32_t kRomExtIdentifierExpected = 0x4552544F;
 
 // TODO: Remove once we have sig_verify integrated.
+// Can be obtained by running `echo -n "OTRE" | openssl dgst -sha256`.
 static const uint32_t kROMExtIdentifierExpectedDigest[8] = {
-    0xe4ce261b, 0xc45462eb, 0xde9b0b29, 0x23f3ccf3,
-    0x933d551c, 0xa85d09fe, 0x82cfed52, 0x6924c711,
+    0x1daa6d65, 0xfb01590b, 0xee565047, 0xa1708a29,
+    0xfe239fa4, 0x91d0dfc9, 0xcf0d3e7a, 0x8b1cffcb,
 };
 
 typedef void(boot_fn)(void);