Skip to content

Commit

Permalink
[sw/silicon_creator] Harden remaining lc_state switches
Browse files Browse the repository at this point in the history
Signed-off-by: Alphan Ulusoy <alphan@google.com>
  • Loading branch information
alphan committed Feb 1, 2022
1 parent 0409944 commit fcca9e5
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 41 deletions.
17 changes: 15 additions & 2 deletions sw/device/silicon_creator/lib/boot_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,14 +492,27 @@ boot_data_t kBootDataDefault = (boot_data_t){
static rom_error_t boot_data_default_get(lifecycle_state_t lc_state,
boot_data_t *boot_data) {
// TODO(#8778): Default boot data.
switch (lc_state) {
switch (launder32(lc_state)) {
case kLcStateTest:
HARDENED_CHECK_EQ(lc_state, kLcStateTest);
*boot_data = kBootDataDefault;
return kErrorOk;
case kLcStateDev:
HARDENED_CHECK_EQ(lc_state, kLcStateDev);
*boot_data = kBootDataDefault;
return kErrorOk;
case kLcStateProd:
HARDENED_CHECK_EQ(lc_state, kLcStateProd);
return kErrorBootDataNotFound;
case kLcStateProdEnd:
HARDENED_CHECK_EQ(lc_state, kLcStateProdEnd);
return kErrorBootDataNotFound;
case kLcStateRma:
HARDENED_CHECK_EQ(lc_state, kLcStateRma);
*boot_data = kBootDataDefault;
return kErrorOk;
default:
return kErrorBootDataNotFound;
HARDENED_UNREACHABLE();
}
}

Expand Down
2 changes: 0 additions & 2 deletions sw/device/silicon_creator/lib/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ enum module_ {
X(kErrorSigverifyBadKey, ERROR_(2, kModuleSigverify, kInvalidArgument)), \
X(kErrorSigverifyBadOtpValue, ERROR_(3, kModuleSigverify, kInternal)), \
X(kErrorSigverifyBadSignature, ERROR_(4, kModuleSigverify, kInvalidArgument)), \
X(kErrorSigverifyBadLcState, ERROR_(5, kModuleSigverify, kInternal)), \
X(kErrorKeymgrInternal, ERROR_(1, kModuleKeymgr, kInternal)), \
X(kErrorManifestBadEntryPoint, ERROR_(1, kModuleManifest, kInternal)), \
X(kErrorManifestBadCodeRegion, ERROR_(2, kModuleManifest, kInternal)), \
Expand Down Expand Up @@ -121,7 +120,6 @@ enum module_ {
X(kErrorLogBadFormatSpecifier, ERROR_(1, kModuleLog, kInternal)), \
X(kErrorBootDataNotFound, ERROR_(1, kModuleBootData, kInternal)), \
X(kErrorBootDataWriteCheck, ERROR_(2, kModuleBootData, kInternal)), \
X(kErrorShutdownBadLcState, ERROR_(1, kModuleShutdown, kInternal)), \
X(kErrorUnknown, 0xFFFFFFFF)
// clang-format on

Expand Down
4 changes: 4 additions & 0 deletions sw/device/silicon_creator/lib/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ sw_silicon_creator_lib_boot_data = declare_dependency(
'boot_data.c',
],
dependencies: [
sw_lib_hardened,
sw_silicon_creator_lib_driver_flash_ctrl,
sw_silicon_creator_lib_driver_hmac,
],
Expand Down Expand Up @@ -87,6 +88,7 @@ sw_silicon_creator_lib_sigverify = declare_dependency(
sw_silicon_creator_lib_driver_otp,
sw_silicon_creator_lib_driver_lifecycle,
sw_lib_bitfield,
sw_lib_hardened,
sw_silicon_creator_lib_otbn_util,
sw_otbn['run_rsa_verify_3072_rr_modexp']['rv32embed_dependency'],
],
Expand All @@ -108,6 +110,7 @@ sw_silicon_creator_lib_shutdown = declare_dependency(
],
dependencies: [
sw_lib_abs_mmio,
sw_lib_hardened,
sw_silicon_creator_lib_driver_alert,
],
),
Expand Down Expand Up @@ -177,6 +180,7 @@ test('sw_silicon_creator_lib_shutdown_unittest', executable(
dependencies: [
sw_vendor_gtest,
sw_silicon_creator_lib_base_mock_abs_mmio,
sw_lib_testing_hardened,
],
native: true,
c_args: ['-DMOCK_ABS_MMIO', '-DOT_OFF_TARGET_TEST'],
Expand Down
14 changes: 8 additions & 6 deletions sw/device/silicon_creator/lib/shutdown.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "sw/device/lib/base/abs_mmio.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/lib/base/memory.h"
#include "sw/device/lib/base/stdasm.h"
Expand Down Expand Up @@ -70,29 +71,30 @@ static size_t clsindex(alert_class_t cls) {
rom_error_t shutdown_init(lifecycle_state_t lc_state) {
// Are we in a lifecycle state which needs alert configuration?
uint32_t lc_shift;
switch (lc_state) {
switch (launder32(lc_state)) {
case kLcStateTest:
HARDENED_CHECK_EQ(lc_state, kLcStateTest);
// Don't configure alerts during manufacturing as OTP may not have been
// programmed yet.
return kErrorOk;
case kLcStateProd:
HARDENED_CHECK_EQ(lc_state, kLcStateProd);
lc_shift = 0;
break;
case kLcStateProdEnd:
HARDENED_CHECK_EQ(lc_state, kLcStateProdEnd);
lc_shift = 8;
break;
case kLcStateDev:
HARDENED_CHECK_EQ(lc_state, kLcStateDev);
lc_shift = 16;
break;
case kLcStateRma:
HARDENED_CHECK_EQ(lc_state, kLcStateRma);
lc_shift = 24;
break;
default:
// Invalid lifecycle state.
shutdown_finalize(kErrorShutdownBadLcState);

// Reachable if using a mock implementation of `shutdown_finalize`.
return kErrorShutdownBadLcState;
HARDENED_UNREACHABLE();
}

// Get the enable and escalation settings for all four alert classes.
Expand Down
17 changes: 9 additions & 8 deletions sw/device/silicon_creator/lib/shutdown_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -557,14 +557,15 @@ TEST_F(ShutdownTest, InitializeManufacturing) {
EXPECT_EQ(shutdown_init(kLcStateTest), kErrorOk);
}

TEST_F(ShutdownTest, InitializeInvalid) {
SetupOtpReads();
ExpectFinalize(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);
class ShutdownDeathTest : public ShutdownTest {};

TEST_F(ShutdownDeathTest, InitializeInvalid) {
ASSERT_DEATH(
{
SetupOtpReads();
shutdown_init(static_cast<lifecycle_state_t>(0));
},
"");
}

TEST(ShutdownModule, RedactErrors) {
Expand Down
31 changes: 16 additions & 15 deletions sw/device/silicon_creator/lib/sigverify.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,26 +201,29 @@ static rom_error_t sigverify_encoded_message_check(
* value.
*
* @param lc_state Life cycle state of the device.
* @param[out] use_sw Use software implementation for signature verification.
* @return Result of the operation.
* @return Whether to use software implementation for signature verification.
*/
static rom_error_t sigverify_use_sw_rsa_verify(lifecycle_state_t lc_state,
hardened_bool_t *use_sw) {
switch (lc_state) {
static hardened_bool_t sigverify_use_sw_rsa_verify(lifecycle_state_t lc_state) {
switch (launder32(lc_state)) {
case kLcStateTest:
HARDENED_CHECK_EQ(lc_state, kLcStateTest);
// Don't read from OTP during manufacturing. Use software
// implementation by default.
*use_sw = kHardenedBoolTrue;
return kErrorOk;
return kHardenedBoolTrue;
case kLcStateDev:
HARDENED_CHECK_EQ(lc_state, kLcStateDev);
return otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET);
case kLcStateProd:
HARDENED_CHECK_EQ(lc_state, kLcStateProd);
return otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET);
case kLcStateProdEnd:
case kLcStateDev:
HARDENED_CHECK_EQ(lc_state, kLcStateProdEnd);
return otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET);
case kLcStateRma:
*use_sw =
otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET);
return kErrorOk;
HARDENED_CHECK_EQ(lc_state, kLcStateRma);
return otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_USE_SW_RSA_VERIFY_OFFSET);
default:
return kErrorSigverifyBadLcState;
HARDENED_UNREACHABLE();
}
}

Expand All @@ -230,9 +233,7 @@ rom_error_t sigverify_rsa_verify(const sigverify_rsa_buffer_t *signature,
lifecycle_state_t lc_state,
uint32_t *flash_exec) {
*flash_exec = UINT32_MAX;
hardened_bool_t use_sw;
RETURN_IF_ERROR(sigverify_use_sw_rsa_verify(lc_state, &use_sw));

hardened_bool_t use_sw = sigverify_use_sw_rsa_verify(lc_state);
sigverify_rsa_buffer_t enc_msg;
switch (use_sw) {
case kHardenedBoolTrue:
Expand Down
17 changes: 9 additions & 8 deletions sw/device/silicon_creator/lib/sigverify_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,16 @@ TEST_F(SigverifyInTestStates, BadSignatureIbex) {
}
}

class SigverifyInInvalidStates : public SigverifyInLcState {};
class SigverifyBadLcStateDeathTest : public SigverifyInLcState {};

TEST_F(SigverifyInInvalidStates, BadLcState) {
uint32_t flash_exec = 0;
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());
TEST_F(SigverifyBadLcStateDeathTest, BadLcState) {
ASSERT_DEATH(
{
uint32_t flash_exec = 0;
sigverify_rsa_verify(&kSignature, &key_, &kTestDigest,
static_cast<lifecycle_state_t>(0), &flash_exec);
},
"");
}

struct UsageConstraintsTestCase {
Expand Down

0 comments on commit fcca9e5

Please sign in to comment.