[sw/silicon_creator] Use OTP to determine which sigverify_mod_exp implementation to use

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/error.h b/sw/device/silicon_creator/lib/error.h
index 5c9314f..64eeb4d 100644
--- a/sw/device/silicon_creator/lib/error.h
+++ b/sw/device/silicon_creator/lib/error.h
@@ -68,6 +68,7 @@
   X(kErrorSigverifyBadEncodedMessage, ERROR_(1, kModuleSigverify, kInvalidArgument)), \
   X(kErrorSigverifyBadExponent,       ERROR_(2, kModuleSigverify, kInvalidArgument)), \
   X(kErrorSigverifyBadKey,            ERROR_(3, kModuleSigverify, kInvalidArgument)), \
+  X(kErrorSigverifyBadOtpValue,       ERROR_(4, kModuleSigverify, kInternal)), \
   X(kErrorKeymgrInternal,             ERROR_(1, kModuleKeymgr, kInternal)), \
   X(kErrorManifestBadLength,          ERROR_(1, kModuleManifest, kInternal)), \
   X(kErrorManifestBadEntryPoint,      ERROR_(2, kModuleManifest, kInternal)), \
diff --git a/sw/device/silicon_creator/lib/meson.build b/sw/device/silicon_creator/lib/meson.build
index 75f8150..4b4c74c 100644
--- a/sw/device/silicon_creator/lib/meson.build
+++ b/sw/device/silicon_creator/lib/meson.build
@@ -52,9 +52,11 @@
     sources: [
       'sigverify_mod_exp_ibex.c',
       'sigverify.c',
+      hw_ip_otp_ctrl_reg_h,
     ],
     dependencies: [
       sw_silicon_creator_lib_driver_hmac,
+      sw_silicon_creator_lib_driver_otp,
     ],
   ),
 )
@@ -167,6 +169,7 @@
     sources: [
       'sigverify_unittest.cc',
       'sigverify.c',
+      hw_ip_otp_ctrl_reg_h,
     ],
     dependencies: [
       sw_vendor_gtest,
diff --git a/sw/device/silicon_creator/lib/sigverify.c b/sw/device/silicon_creator/lib/sigverify.c
index ec0f7a6..e679103 100644
--- a/sw/device/silicon_creator/lib/sigverify.c
+++ b/sw/device/silicon_creator/lib/sigverify.c
@@ -4,12 +4,15 @@
 
 #include "sw/device/silicon_creator/lib/sigverify.h"
 
+#include "sw/device/lib/base/hardened.h"
 #include "sw/device/lib/base/memory.h"
 #include "sw/device/lib/base/mmio.h"
 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
+#include "sw/device/silicon_creator/lib/drivers/otp.h"
 #include "sw/device/silicon_creator/lib/sigverify_mod_exp.h"
 
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
+#include "otp_ctrl_regs.h"
 
 /**
  * Checks the padding and the digest of an EMSA-PKCS1-v1_5 encoded message.
@@ -78,10 +81,17 @@
   RETURN_IF_ERROR(hmac_sha256_update(signed_message, signed_message_len));
   RETURN_IF_ERROR(hmac_sha256_final(&act_digest));
 
-  // FIXME: Choose between Ibex and OTBN using OTP.
-  // FIXME: OTBN modular exponentiation.
   sigverify_rsa_buffer_t enc_msg;
-  RETURN_IF_ERROR(sigverify_mod_exp_ibex(key, signature, &enc_msg));
+  switch (otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET)) {
+    case kHardenedBoolTrue:
+      RETURN_IF_ERROR(sigverify_mod_exp_ibex(key, signature, &enc_msg));
+      break;
+    case kHardenedBoolFalse:
+      // FIXME: OTBN modular exponentiation.
+      break;
+    default:
+      return kErrorSigverifyBadOtpValue;
+  }
   RETURN_IF_ERROR(sigverify_padding_and_digest_check(&enc_msg, &act_digest));
 
   return kErrorOk;
diff --git a/sw/device/silicon_creator/lib/sigverify_functest.c b/sw/device/silicon_creator/lib/sigverify_functest.c
index e4816b8..a844143 100644
--- a/sw/device/silicon_creator/lib/sigverify_functest.c
+++ b/sw/device/silicon_creator/lib/sigverify_functest.c
@@ -2,11 +2,15 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
+#include "sw/device/silicon_creator/lib/base/sec_mmio.h"
 #include "sw/device/silicon_creator/lib/sigverify.h"
 #include "sw/device/silicon_creator/lib/test_main.h"
 
 static const char kMessage[] = "test message";
 
+// sec_mmio (used by the OTP driver) requires this symbol to be defined.
+sec_mmio_ctx_t sec_mmio_ctx;
+
 // See sw/device/silicon_creator/keys/README.md for more details on how to
 // update the structs below.
 
diff --git a/sw/device/silicon_creator/lib/sigverify_unittest.cc b/sw/device/silicon_creator/lib/sigverify_unittest.cc
index 19280cf..b8e44aa 100644
--- a/sw/device/silicon_creator/lib/sigverify_unittest.cc
+++ b/sw/device/silicon_creator/lib/sigverify_unittest.cc
@@ -6,12 +6,14 @@
 
 #include <cstring>
 
-#include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include "sw/device/lib/base/hardened.h"
 #include "sw/device/silicon_creator/lib/drivers/mock_hmac.h"
+#include "sw/device/silicon_creator/lib/drivers/mock_otp.h"
 #include "sw/device/silicon_creator/lib/mock_sigverify_mod_exp.h"
 
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
+#include "otp_ctrl_regs.h"
 
 namespace sigverify_unittest {
 namespace {
@@ -87,6 +89,7 @@
  protected:
   mask_rom_test::MockSigverifyModExp sigverify_mod_exp_;
   mask_rom_test::MockHmac hmac_;
+  mask_rom_test::MockOtp otp_;
   // The content of this key is not significant since we use mocks.
   sigverify_rsa_key_t key_{};
 };
@@ -97,6 +100,9 @@
       .WillOnce(Return(kErrorOk));
   EXPECT_CALL(hmac_, sha256_final(NotNull()))
       .WillOnce(DoAll(SetArgPointee<0>(kTestDigest), Return(kErrorOk)));
+  EXPECT_CALL(otp_,
+              read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET))
+      .WillOnce(Return(kHardenedBoolTrue));
   EXPECT_CALL(sigverify_mod_exp_, ibex(&key_, &kSignature, NotNull()))
       .WillOnce(DoAll(SetArgPointee<2>(kEncMsg), Return(kErrorOk)));
 
@@ -118,6 +124,9 @@
         .WillOnce(Return(kErrorOk));
     EXPECT_CALL(hmac_, sha256_final(NotNull()))
         .WillOnce(DoAll(SetArgPointee<0>(kTestDigest), Return(kErrorOk)));
+    EXPECT_CALL(otp_,
+                read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET))
+        .WillOnce(Return(kHardenedBoolTrue));
     EXPECT_CALL(sigverify_mod_exp_, ibex(&key_, &kSignature, NotNull()))
         .WillOnce(DoAll(SetArgPointee<2>(bad_enc_msg), Return(kErrorOk)));
 
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 74398e6..d0c8a68 100644
--- a/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
+++ b/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
@@ -214,6 +214,7 @@
       public testing::WithParamInterface<RsaVerifyTestCase> {
  protected:
   mask_rom_test::MockHmac hmac_;
+  mask_rom_test::MockOtp otp_;
 };
 
 TEST_P(SigverifyRsaVerify, Ibex) {
@@ -222,6 +223,10 @@
       .WillOnce(Return(kErrorOk));
   EXPECT_CALL(hmac_, sha256_final(NotNull()))
       .WillOnce(DoAll(SetArgPointee<0>(kDigest), Return(kErrorOk)));
+  EXPECT_CALL(otp_,
+              read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET))
+      .WillOnce(Return(kHardenedBoolTrue));
+
   EXPECT_EQ(sigverify_rsa_verify(kMessage.data(), kMessage.size(),
                                  &GetParam().sig, GetParam().key),
             kErrorOk);