Skip to content

Commit

Permalink
[rom] fix bug in ROM that computes OTP measurements
Browse files Browse the repository at this point in the history
This fixes a bug in the ROM that computes OTP measurements to populate
the keymgr attestation binding CSRs, if the OTP fuse
(`OWNER_SW_CFG_ROM_KEYMGR_OTP_MEAS_EN`) to request this is set.
Additionally, this fixes the corresponding ROM E2E test as well, and
enhances its robustness.

Signed-off-by: Tim Trippel <[email protected]>
  • Loading branch information
timothytrippel committed Jan 23, 2025
1 parent fb0b4fb commit 27a35e9
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 33 deletions.
14 changes: 7 additions & 7 deletions sw/device/silicon_creator/lib/drivers/otp.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,37 @@ const otp_partition_info_t kOtpPartitions[] = {
.start_addr = OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET,
.size = OTP_CTRL_PARAM_CREATOR_SW_CFG_SIZE -
OTP_CTRL_PARAM_CREATOR_SW_CFG_DIGEST_SIZE,
.digest_addr = OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_REG_OFFSET,
.digest_reg_addr = OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_REG_OFFSET,
.align_mask = 0x3},
[kOtpPartitionOwnerSwCfg] = {
.start_addr = OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET,
.size = OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE -
OTP_CTRL_PARAM_OWNER_SW_CFG_DIGEST_SIZE,
.digest_addr = OTP_CTRL_OWNER_SW_CFG_DIGEST_0_REG_OFFSET,
.digest_reg_addr = OTP_CTRL_OWNER_SW_CFG_DIGEST_0_REG_OFFSET,
.align_mask = 0x3},
[kOtpPartitionRotCreatorAuthCodesign] = {
.start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET,
.size = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE -
OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_DIGEST_SIZE,
.digest_addr = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_REG_OFFSET,
.digest_reg_addr = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_REG_OFFSET,
.align_mask = 0x3},
[kOtpPartitionRotCreatorAuthState] = {
.start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET,
.size = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE -
OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_DIGEST_SIZE,
.digest_addr = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_REG_OFFSET,
.digest_reg_addr = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_REG_OFFSET,
.align_mask = 0x3},
[kOtpPartitionHwCfg0] = {
.start_addr = OTP_CTRL_PARAM_HW_CFG0_OFFSET,
.size = OTP_CTRL_PARAM_HW_CFG0_SIZE -
OTP_CTRL_PARAM_HW_CFG0_DIGEST_SIZE,
.digest_addr = OTP_CTRL_HW_CFG0_DIGEST_0_REG_OFFSET,
.digest_reg_addr = OTP_CTRL_HW_CFG0_DIGEST_0_REG_OFFSET,
.align_mask = 0x3},
[kOtpPartitionHwCfg1] = {
.start_addr = OTP_CTRL_PARAM_HW_CFG1_OFFSET,
.size = OTP_CTRL_PARAM_HW_CFG1_SIZE -
OTP_CTRL_PARAM_HW_CFG1_DIGEST_SIZE,
.digest_addr = OTP_CTRL_HW_CFG1_DIGEST_0_REG_OFFSET,
.digest_reg_addr = OTP_CTRL_HW_CFG1_DIGEST_0_REG_OFFSET,
.align_mask = 0x3},
};
// clang-format on
Expand Down Expand Up @@ -86,7 +86,7 @@ void otp_read(uint32_t address, uint32_t *data, size_t num_words) {
}

uint64_t otp_partition_digest_read(otp_partition_t partition) {
uint32_t reg_offset = kBase + kOtpPartitions[partition].digest_addr;
uint32_t reg_offset = kBase + kOtpPartitions[partition].digest_reg_addr;
uint64_t value = sec_mmio_read32(reg_offset + sizeof(uint32_t));
value <<= 32;
value |= sec_mmio_read32(reg_offset);
Expand Down
5 changes: 3 additions & 2 deletions sw/device/silicon_creator/lib/drivers/otp.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ typedef struct otp_partition_info {
*/
size_t size;
/**
* The absolute OTP address at which this partition's digest starts.
* The OTP digest CSR (where the digest is buffered) address for this
* partition.
*/
uint32_t digest_addr;
uint32_t digest_reg_addr;
/**
* The alignment mask for this partition.
*
Expand Down
5 changes: 4 additions & 1 deletion sw/device/silicon_creator/rom/e2e/keymgr/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ load(
)
load(
"//rules/opentitan:defs.bzl",
"cw310_params",
"dv_params",
"fpga_params",
"opentitan_test",
Expand Down Expand Up @@ -90,7 +89,11 @@ rom_e2e_keymgr_init_configs = [
),
deps = [
"//sw/device/lib/dif:keymgr",
"//sw/device/lib/dif:otp_ctrl",
"//sw/device/lib/dif:rstmgr",
"//sw/device/lib/testing:keymgr_testutils",
"//sw/device/lib/testing:otp_ctrl_testutils",
"//sw/device/lib/testing:rstmgr_testutils",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_a",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:hmac",
Expand Down
80 changes: 59 additions & 21 deletions sw/device/silicon_creator/rom/e2e/keymgr/rom_e2e_keymgr_init_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@

#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_keymgr.h"
#include "sw/device/lib/dif/dif_otp_ctrl.h"
#include "sw/device/lib/dif/dif_rstmgr.h"
#include "sw/device/lib/runtime/ibex.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/keymgr_testutils.h"
#include "sw/device/lib/testing/otp_ctrl_testutils.h"
#include "sw/device/lib/testing/rstmgr_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"
#include "sw/device/silicon_creator/lib/base/boot_measurements.h"
Expand All @@ -23,12 +27,49 @@

OTTF_DEFINE_TEST_CONFIG();

static dif_keymgr_t keymgr;
static dif_otp_ctrl_t otp_ctrl;
static dif_rstmgr_t rstmgr;
static uint32_t otp_state[kHmacDigestNumWords + 4] = {0};

static void print_otp_sw_cfg_digests(void) {
uint64_t creator_digest, owner_digest = 0;
CHECK_DIF_OK(dif_otp_ctrl_get_digest(
&otp_ctrl, kDifOtpCtrlPartitionCreatorSwCfg, &creator_digest));
CHECK_DIF_OK(dif_otp_ctrl_get_digest(
&otp_ctrl, kDifOtpCtrlPartitionOwnerSwCfg, &owner_digest));
LOG_INFO("CreatorSwCfg Digest: 0x%08x%08x", (uint32_t)(creator_digest >> 32),
(uint32_t)creator_digest);
LOG_INFO("OwnerSwCfg Digest: 0x%08x%08x", (uint32_t)(owner_digest >> 32),
(uint32_t)owner_digest);
}

bool test_main(void) {
dif_keymgr_t keymgr;
CHECK_DIF_OK(dif_keymgr_init(
mmio_region_from_addr(TOP_EARLGREY_KEYMGR_BASE_ADDR), &keymgr));
CHECK_DIF_OK(dif_otp_ctrl_init(
mmio_region_from_addr(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR), &otp_ctrl));
CHECK_DIF_OK(dif_rstmgr_init(
mmio_region_from_addr(TOP_EARLGREY_RSTMGR_AON_BASE_ADDR), &rstmgr));

/*// Lock OTP *SwCfg partitions if this is the first boot and reset.*/
if (UNWRAP(rstmgr_testutils_is_reset_info(&rstmgr, kDifRstmgrResetInfoPor))) {
LOG_INFO("Power on reset. Locking OTP *SwCfg partitions ...");
const uint64_t kFakeOtpDigest = 0xaaaabbbbccccdddd;
CHECK_STATUS_OK(otp_ctrl_testutils_lock_partition(
&otp_ctrl, kDifOtpCtrlPartitionCreatorSwCfg,
/*digest=*/kFakeOtpDigest));
CHECK_STATUS_OK(otp_ctrl_testutils_lock_partition(
&otp_ctrl, kDifOtpCtrlPartitionOwnerSwCfg,
/*digest=*/kFakeOtpDigest));
rstmgr_testutils_reason_clear();
LOG_INFO("Issuing a software reset ...");
CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
wait_for_interrupt();
} else {
print_otp_sw_cfg_digests();
LOG_INFO("SW reset. Executing test ...");
}

CHECK_STATUS_OK(keymgr_testutils_check_state(&keymgr, kDifKeymgrStateReset));

Expand All @@ -39,34 +80,31 @@ bool test_main(void) {

if (otp_read32(OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_KEYMGR_OTP_MEAS_EN_OFFSET) ==
kHardenedBoolTrue) {
LOG_INFO("ROM OTP measurement feature ENABLED.");
// Check that the attestation is equal to the digest of concatenations of:
// - the digest of the CreatorSwCfg partition,
// - the digest of the OwnerSwCfg partition,
// - the SHA256 integrity hash of the first stage boot keys.
otp_dai_read(kOtpPartitionCreatorSwCfg,
/*relative_address=*/
kOtpPartitions[kOtpPartitionCreatorSwCfg].digest_addr -
OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET,
otp_state,
/*num_words=*/2);
otp_dai_read(kOtpPartitionOwnerSwCfg,
/*relative_address=*/
kOtpPartitions[kOtpPartitionOwnerSwCfg].digest_addr -
OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET,
&otp_state[2],
/*num_words=*/2);
otp_dai_read(kOtpPartitionRotCreatorAuthCodesign,
/*relative_address=*/
OTP_CTRL_PARAM_ROTCREATORAUTHCODESIGNBLOCKSHA2_256HASHOFFSET -
OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET,
&otp_state[4],
/*num_words=*/kHmacDigestNumWords);
CHECK_DIF_OK(dif_otp_ctrl_get_digest(
&otp_ctrl, kDifOtpCtrlPartitionCreatorSwCfg, (uint64_t *)otp_state));
CHECK_DIF_OK(dif_otp_ctrl_get_digest(
&otp_ctrl, kDifOtpCtrlPartitionOwnerSwCfg, (uint64_t *)&otp_state[2]));
CHECK_STATUS_OK(otp_ctrl_testutils_dai_read32_array(
&otp_ctrl, kDifOtpCtrlPartitionRotCreatorAuthCodesign,
OTP_CTRL_PARAM_ROTCREATORAUTHCODESIGNBLOCKSHA2_256HASHOFFSET -
OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET,
&otp_state[4], /*num_words=*/kHmacDigestNumWords));
hmac_digest_t otp_measurement;
hmac_sha256(otp_state, (kHmacDigestNumWords + 4) * sizeof(uint32_t),
&otp_measurement);
hmac_sha256(otp_state, sizeof(otp_state), &otp_measurement);
LOG_INFO("OTP CreatorSwCfg Digest: 0x%08x%08x", otp_state[1], otp_state[0]);
LOG_INFO("OTP OwnerSwCfg Digest: 0x%08x%08x", otp_state[3], otp_state[2]);
LOG_INFO("OTP Root Keys Digest: 0x%08x%08x%08x%08x%08x%08x%08x%08x",
otp_state[11], otp_state[10], otp_state[9], otp_state[8],
otp_state[7], otp_state[6], otp_state[5], otp_state[4]);
CHECK_ARRAYS_EQ(bindings.attestation, otp_measurement.digest,
ARRAYSIZE(bindings.attestation));
} else {
LOG_INFO("ROM OTP measurement feature DISABLED.");
// Check that the attestation is equal to `binding_value` field of the
// manifest.
CHECK_ARRAYS_EQ(bindings.attestation, manifest->binding_value.data,
Expand Down
4 changes: 2 additions & 2 deletions sw/device/silicon_creator/rom/rom.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,12 @@ static rom_error_t rom_measure_otp_partitions(
hmac_sha256_update(
(unsigned char *)(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR +
OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_REG_OFFSET),
OTP_CTRL_PARAM_CREATOR_SW_CFG_DIGEST_OFFSET),
sizeof(uint64_t));
hmac_sha256_update(
(unsigned char *)(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR +
OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
OTP_CTRL_OWNER_SW_CFG_DIGEST_0_REG_OFFSET),
OTP_CTRL_PARAM_OWNER_SW_CFG_DIGEST_OFFSET),
sizeof(uint64_t));
hmac_sha256_update(sigverify_ctx.keys.integrity_measurement.digest,
kHmacDigestNumBytes);
Expand Down

0 comments on commit 27a35e9

Please sign in to comment.