[sw/silicon_creator] Move digest computation out of sigverify_rsa_verify()
This change moves the digest computation out of sigverify_rsa_verify()
so that we can customize how it is computed, e.g. to implement usage
constraints described in #5956.
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/meson.build b/sw/device/silicon_creator/lib/meson.build
index bd21618..62000c3 100644
--- a/sw/device/silicon_creator/lib/meson.build
+++ b/sw/device/silicon_creator/lib/meson.build
@@ -56,7 +56,6 @@
hw_ip_otp_ctrl_reg_h,
],
dependencies: [
- sw_silicon_creator_lib_driver_hmac,
sw_silicon_creator_lib_driver_otp,
],
),
@@ -218,6 +217,7 @@
],
dependencies: [
sw_silicon_creator_lib_sigverify,
+ sw_silicon_creator_lib_driver_hmac,
],
),
)
diff --git a/sw/device/silicon_creator/lib/sigverify.c b/sw/device/silicon_creator/lib/sigverify.c
index fd08c11..31e6d7a 100644
--- a/sw/device/silicon_creator/lib/sigverify.c
+++ b/sw/device/silicon_creator/lib/sigverify.c
@@ -7,7 +7,6 @@
#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"
@@ -112,16 +111,10 @@
}
}
-rom_error_t sigverify_rsa_verify(const void *signed_message,
- size_t signed_message_len,
- const sigverify_rsa_buffer_t *signature,
+rom_error_t sigverify_rsa_verify(const sigverify_rsa_buffer_t *signature,
const sigverify_rsa_key_t *key,
+ const hmac_digest_t *act_digest,
lifecycle_state_t lc_state) {
- hmac_digest_t act_digest;
- hmac_sha256_init();
- RETURN_IF_ERROR(hmac_sha256_update(signed_message, signed_message_len));
- RETURN_IF_ERROR(hmac_sha256_final(&act_digest));
-
hardened_bool_t use_sw;
RETURN_IF_ERROR(sigverify_use_sw_rsa_verify(lc_state, &use_sw));
@@ -136,7 +129,7 @@
default:
return kErrorSigverifyBadOtpValue;
}
- RETURN_IF_ERROR(sigverify_padding_and_digest_check(&enc_msg, &act_digest));
+ RETURN_IF_ERROR(sigverify_padding_and_digest_check(&enc_msg, act_digest));
return kErrorOk;
}
diff --git a/sw/device/silicon_creator/lib/sigverify.h b/sw/device/silicon_creator/lib/sigverify.h
index 683d654..4e6bf90 100644
--- a/sw/device/silicon_creator/lib/sigverify.h
+++ b/sw/device/silicon_creator/lib/sigverify.h
@@ -8,6 +8,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "sw/device/silicon_creator/lib/drivers/hmac.h"
#include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
#include "sw/device/silicon_creator/lib/error.h"
#include "sw/device/silicon_creator/lib/sigverify_rsa_key.h"
@@ -36,17 +37,15 @@
* The actual implementation that is used (software or OTBN) is determined by
* the life cycle state of the device and the OTP value.
*
- * @param signed_message Message whose signature is to be verified.
- * @param signed_message_len Length of the signed message in bytes.
* @param signature Signature to be verified.
* @param key Signer's RSA public key.
+ * @param act_digest Actual digest of the message being verified.
* @param lc_state Life cycle state of the device.
* @return Result of the operation.
*/
-rom_error_t sigverify_rsa_verify(const void *signed_message,
- size_t signed_message_len,
- const sigverify_rsa_buffer_t *signature,
+rom_error_t sigverify_rsa_verify(const sigverify_rsa_buffer_t *signature,
const sigverify_rsa_key_t *key,
+ const hmac_digest_t *act_digest,
lifecycle_state_t lc_state);
#ifdef __cplusplus
diff --git a/sw/device/silicon_creator/lib/sigverify_functest.c b/sw/device/silicon_creator/lib/sigverify_functest.c
index 4b4d0f5..312dd2b 100644
--- a/sw/device/silicon_creator/lib/sigverify_functest.c
+++ b/sw/device/silicon_creator/lib/sigverify_functest.c
@@ -2,12 +2,16 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
+#include "sw/device/lib/testing/check.h"
#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";
+// Digest of the test message above.
+hmac_digest_t act_digest;
+
// sec_mmio (used by the OTP driver) requires this symbol to be defined.
sec_mmio_ctx_t sec_mmio_ctx;
@@ -122,20 +126,27 @@
.exponent = 3,
};
+rom_error_t compute_digest(void) {
+ hmac_sha256_init();
+ RETURN_IF_ERROR(hmac_sha256_update(&kMessage, sizeof(kMessage) - 1));
+ RETURN_IF_ERROR(hmac_sha256_final(&act_digest));
+ return kErrorOk;
+}
+
rom_error_t sigverify_test_exp_3(void) {
- return sigverify_rsa_verify(&kMessage, sizeof(kMessage) - 1, &kSignatureExp3,
- &kKeyExp3, kLcStateRma);
+ return sigverify_rsa_verify(&kSignatureExp3, &kKeyExp3, &act_digest,
+ kLcStateRma);
}
rom_error_t sigverify_test_exp_65537(void) {
- return sigverify_rsa_verify(&kMessage, sizeof(kMessage) - 1,
- &kSignatureExp65537, &kKeyExp65537, kLcStateRma);
+ return sigverify_rsa_verify(&kSignatureExp65537, &kKeyExp65537, &act_digest,
+ kLcStateRma);
}
rom_error_t sigverify_test_negative(void) {
// Signature verification should fail when using the wrong signature.
- if (sigverify_rsa_verify(&kMessage, sizeof(kMessage) - 1, &kSignatureExp65537,
- &kKeyExp3, kLcStateRma) == kErrorOk) {
+ if (sigverify_rsa_verify(&kSignatureExp65537, &kKeyExp3, &act_digest,
+ kLcStateRma) == kErrorOk) {
return kErrorUnknown;
}
return kErrorOk;
@@ -145,6 +156,9 @@
bool test_main(void) {
rom_error_t result = kErrorOk;
+
+ CHECK(compute_digest() == kErrorOk);
+
EXECUTE_TEST(result, sigverify_test_exp_3);
EXECUTE_TEST(result, sigverify_test_exp_65537);
EXECUTE_TEST(result, sigverify_test_negative);
diff --git a/sw/device/silicon_creator/lib/sigverify_unittest.cc b/sw/device/silicon_creator/lib/sigverify_unittest.cc
index 7b4aee7..61d7caa 100644
--- a/sw/device/silicon_creator/lib/sigverify_unittest.cc
+++ b/sw/device/silicon_creator/lib/sigverify_unittest.cc
@@ -81,10 +81,8 @@
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff,
}};
-// The contents of `kSignedRegion` and `kSignature` are not significant since we
-// use mocks. `kSignedRegion` is initialized this way only for consistency with
-// `kTestDigest`.
-constexpr std::array<uint8_t, 4> kSignedRegion{'t', 'e', 's', 't'};
+// The value of `kSignature` is not significant since we use mocks for
+// `sigverify_mod_exp_ibex()` and `sigverify_mod_exp_otbn()`.
constexpr sigverify_rsa_buffer_t kSignature{};
/**
@@ -135,15 +133,6 @@
: public mask_rom_test::MaskRomTest,
public testing::WithParamInterface<lifecycle_state_t> {
protected:
- void ExpectSha256() {
- EXPECT_CALL(hmac_, sha256_init());
- EXPECT_CALL(hmac_,
- sha256_update(kSignedRegion.data(), sizeof(kSignedRegion)))
- .WillOnce(Return(kErrorOk));
- EXPECT_CALL(hmac_, sha256_final(NotNull()))
- .WillOnce(DoAll(SetArgPointee<0>(kTestDigest), Return(kErrorOk)));
- }
-
mask_rom_test::MockSigverifyModExpIbex sigverify_mod_exp_ibex_;
mask_rom_test::MockSigverifyModExpOtbn sigverify_mod_exp_otbn_;
mask_rom_test::MockHmac hmac_;
@@ -155,39 +144,33 @@
class SigverifyInNonTestStates : public SigverifyInLcState {};
TEST_P(SigverifyInNonTestStates, BadOtpValue) {
- ExpectSha256();
EXPECT_CALL(otp_,
read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET))
.WillOnce(Return(0xA5A5A5A5));
- EXPECT_EQ(sigverify_rsa_verify(kSignedRegion.data(), sizeof(kSignedRegion),
- &kSignature, &key_, GetParam()),
+ EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam()),
kErrorSigverifyBadOtpValue);
}
TEST_P(SigverifyInNonTestStates, GoodSignatureIbex) {
- ExpectSha256();
EXPECT_CALL(otp_,
read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET))
.WillOnce(Return(kHardenedBoolTrue));
EXPECT_CALL(sigverify_mod_exp_ibex_, mod_exp(&key_, &kSignature, NotNull()))
.WillOnce(DoAll(SetArgPointee<2>(kEncMsg), Return(kErrorOk)));
- EXPECT_EQ(sigverify_rsa_verify(kSignedRegion.data(), sizeof(kSignedRegion),
- &kSignature, &key_, GetParam()),
+ EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam()),
kErrorOk);
}
TEST_P(SigverifyInNonTestStates, GoodSignatureOtbn) {
- ExpectSha256();
EXPECT_CALL(otp_,
read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET))
.WillOnce(Return(kHardenedBoolFalse));
EXPECT_CALL(sigverify_mod_exp_otbn_, mod_exp(&key_, &kSignature, NotNull()))
.WillOnce(DoAll(SetArgPointee<2>(kEncMsg), Return(kErrorOk)));
- EXPECT_EQ(sigverify_rsa_verify(kSignedRegion.data(), sizeof(kSignedRegion),
- &kSignature, &key_, GetParam()),
+ EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam()),
kErrorOk);
}
@@ -198,16 +181,15 @@
auto bad_enc_msg = kEncMsg;
bad_enc_msg.data[i] = ~bad_enc_msg.data[i];
- ExpectSha256();
EXPECT_CALL(otp_,
read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET))
.WillOnce(Return(kHardenedBoolFalse));
EXPECT_CALL(sigverify_mod_exp_otbn_, mod_exp(&key_, &kSignature, NotNull()))
.WillOnce(DoAll(SetArgPointee<2>(bad_enc_msg), Return(kErrorOk)));
- EXPECT_EQ(sigverify_rsa_verify(kSignedRegion.data(), sizeof(kSignedRegion),
- &kSignature, &key_, GetParam()),
- kErrorSigverifyBadEncodedMessage);
+ EXPECT_EQ(
+ sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam()),
+ kErrorSigverifyBadEncodedMessage);
}
}
@@ -217,12 +199,10 @@
class SigverifyInTestStates : public SigverifyInLcState {};
TEST_P(SigverifyInTestStates, GoodSignatureIbex) {
- ExpectSha256();
EXPECT_CALL(sigverify_mod_exp_ibex_, mod_exp(&key_, &kSignature, NotNull()))
.WillOnce(DoAll(SetArgPointee<2>(kEncMsg), Return(kErrorOk)));
- EXPECT_EQ(sigverify_rsa_verify(kSignedRegion.data(), sizeof(kSignedRegion),
- &kSignature, &key_, GetParam()),
+ EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam()),
kErrorOk);
}
@@ -233,13 +213,12 @@
auto bad_enc_msg = kEncMsg;
bad_enc_msg.data[i] = ~bad_enc_msg.data[i];
- ExpectSha256();
EXPECT_CALL(sigverify_mod_exp_ibex_, mod_exp(&key_, &kSignature, NotNull()))
.WillOnce(DoAll(SetArgPointee<2>(bad_enc_msg), Return(kErrorOk)));
- EXPECT_EQ(sigverify_rsa_verify(kSignedRegion.data(), sizeof(kSignedRegion),
- &kSignature, &key_, GetParam()),
- kErrorSigverifyBadEncodedMessage);
+ EXPECT_EQ(
+ sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam()),
+ kErrorSigverifyBadEncodedMessage);
}
}
@@ -249,10 +228,7 @@
class SigverifyInInvalidStates : public SigverifyInLcState {};
TEST_P(SigverifyInInvalidStates, BadLcState) {
- ExpectSha256();
-
- EXPECT_EQ(sigverify_rsa_verify(kSignedRegion.data(), sizeof(kSignedRegion),
- &kSignature, &key_, GetParam()),
+ EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam()),
kErrorSigverifyBadLcState);
}
diff --git a/sw/device/silicon_creator/mask_rom/mask_rom.c b/sw/device/silicon_creator/mask_rom/mask_rom.c
index 50ed8c7..222c87b 100644
--- a/sw/device/silicon_creator/mask_rom/mask_rom.c
+++ b/sw/device/silicon_creator/mask_rom/mask_rom.c
@@ -94,9 +94,13 @@
// TODO(#5956): Manifest usage constraints.
manifest_signed_region_t signed_region = manifest_signed_region_get(manifest);
- RETURN_IF_ERROR(sigverify_rsa_verify(signed_region.start,
- signed_region.length,
- &manifest->signature, key, lc_state));
+ hmac_sha256_init();
+ RETURN_IF_ERROR(
+ hmac_sha256_update(signed_region.start, signed_region.length));
+ hmac_digest_t act_digest;
+ RETURN_IF_ERROR(hmac_sha256_final(&act_digest));
+ RETURN_IF_ERROR(
+ sigverify_rsa_verify(&manifest->signature, key, &act_digest, lc_state));
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 427b900..52725ad 100644
--- a/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
+++ b/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
@@ -24,10 +24,7 @@
namespace sigverify_keys_unittest {
namespace {
-using ::testing::DoAll;
-using ::testing::NotNull;
using ::testing::Return;
-using ::testing::SetArgPointee;
/**
* Mock keys used in tests.
@@ -367,7 +364,6 @@
* xxd -p -c 4 | tac | sed 's|.*|0x&,|'
* ```
*/
-constexpr std::array<uint8_t, 4> kMessage{'t', 'e', 's', 't'};
constexpr hmac_digest_t kDigest = {
.digest =
{
@@ -474,17 +470,12 @@
};
TEST_P(SigverifyRsaVerify, Ibex) {
- EXPECT_CALL(hmac_, sha256_init());
- EXPECT_CALL(hmac_, sha256_update(kMessage.data(), kMessage.size()))
- .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, kLcStateProd),
+ EXPECT_EQ(sigverify_rsa_verify(&GetParam().sig, GetParam().key, &kDigest,
+ kLcStateProd),
kErrorOk);
}