Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[keymgr_dpe] Port keymgr_dpe_key_derivation test from integrated_dev #26350

Merged
merged 5 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
309 changes: 281 additions & 28 deletions sw/device/lib/dif/dif_otp_ctrl.c

Large diffs are not rendered by default.

160 changes: 160 additions & 0 deletions sw/device/lib/dif/dif_otp_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ typedef enum dif_otp_ctrl_partition {
* modes if verification fails.
*/
kDifOtpCtrlPartitionOwnerSwCfg,
#if defined(OPENTITAN_IS_EARLGREY)
/**
* This OTP partition is used to store four P-256 keys and four Sphincs+ keys.
*
Expand All @@ -78,6 +79,90 @@ typedef enum dif_otp_ctrl_partition {
* EarlGrey.
*/
kDifOtpCtrlPartitionRotCreatorAuthState,
#elif defined(OPENTITAN_IS_DARJEELING)
/**
* SW managed asset ownership states partition.
*
* Multibit enable value for the tracking the asset ownership states.
* Note that the states can be written multiple times in a device lifetime.
* The values to be written are engineered in the same way as the LC_CTRL
* state encoding words so that the ECC encoding remains valid even after
* updating the values.
*
* The constants can be found in the lc_ctrl_state_pkg.sv package.
*
* The programming order has to adhere to:
*
* OWNERSHIP_ST_RAW (factory all-zero state) ->
* OWNERSHIP_ST_LOCKED0 ->
* OWNERSHIP_ST_RELEASED0 ->
* ...
* OWNERSHIP_ST_SCRAPPED
*
* Note that if there are less than 4 slots available the higher slot states
* become logically equivalent to OWNERSHIP_SCRAPPED (firmware has to handle
* this correctly).
*/
kDifOtpCtrlPartitionOwnershipSlotState,
/**
* Software managed creator partition.
*
*/
kDifOtpCtrlPartitionRotCreatorAuth,
/**
* Software managed owner slot 0 partition.
*
*/
kDifOtpCtrlPartitionRotOwnerAuthSlot0,
/**
* Software managed owner slot 1 partition.
*
*/
kDifOtpCtrlPartitionRotOwnerAuthSlot1,
/**
* Software managed platform integrator slot 0 partition.
*
*/
kDifOtpCtrlPartitionPlatIntegAuthSlot0,
/**
* Software managed platform integrator slot 1 partition.
*
*/
kDifOtpCtrlPartitionPlatIntegAuthSlot1,
/**
* Software managed platform owner slot 0 partition.
*
*/
kDifOtpCtrlPartitionPlatOwnerAuthSlot0,
/**
* Software managed platform owner slot 1 partition.
*
*/
kDifOtpCtrlPartitionPlatOwnerAuthSlot1,
/**
* Software managed platform owner slot 2 partition.
*
*/
kDifOtpCtrlPartitionPlatOwnerAuthSlot2,
/**
* Software managed platform owner slot 3 partition.
*
*/
kDifOtpCtrlPartitionPlatOwnerAuthSlot3,
/**
* Anti-replay protection Strike Counters partition.
*
*/
kDifOtpCtrlPartitionExtNvm,
/**
* ROM Patch Code section.
*
* May contain multiple signed ROM2 patches.
*/
kDifOtpCtrlPartitionRomPatch,
#else
#error "dif_otp_ctrl does not support this top"
#endif
/**
* Hardware configuration 0 partition.
*
Expand Down Expand Up @@ -108,6 +193,18 @@ typedef enum dif_otp_ctrl_partition {
* This contains RMA unlock token, creator root key, and creator seed.
*/
kDifOtpCtrlPartitionSecret2,
#if defined(OPENTITAN_IS_DARJEELING)
/**
* Secret partition 3.
*
* This contains the owner seed.
*/
kDifOtpCtrlPartitionSecret3,
#elif defined(OPENTITAN_IS_EARLGREY)
// Earlgrey only has 3 secret partitions.
#else
#error "dif_otp_ctrl does not support this top"
#endif
/**
* Lifecycle partition.
*
Expand Down Expand Up @@ -182,6 +279,7 @@ typedef enum dif_otp_ctrl_status_code {
* Indicates an error occurred in the `OwnerSwCfg` partition.
*/
kDifOtpCtrlStatusCodeOwnerSwCfgError,
#if defined(OPENTITAN_IS_EARLGREY)
/**
* Indicates an error occurred in the `RotCreatorAuthCodesign` partition.
*/
Expand All @@ -190,6 +288,58 @@ typedef enum dif_otp_ctrl_status_code {
* Indicates an error occurred in the `RotCreatorAuthState` partition.
*/
kDifOtpCtrlStatusCodeRotCreatorAuthStateError,
#elif defined(OPENTITAN_IS_DARJEELING)
/**
* Indicates an error occurred in the `OwnershipSlotState` partition.
*/
kDifOtpCtrlStatusCodeOwnershipSlotStateError,
/**
* Indicates an error occurred in the `RotCreatorAuth` partition.
*/
kDifOtpCtrlStatusCodeRotCreatorAuthError,
/**
* Indicates an error occurred in the `RotOwnerAuthSlot0` partition.
*/
kDifOtpCtrlStatusCodeRotOwnerAuthSlot0Error,
/**
* Indicates an error occurred in the `RotOwnerAuthSlot1` partition.
*/
kDifOtpCtrlStatusCodeRotOwnerAuthSlot1Error,
/**
* Indicates an error occurred in the `PlatIntegAuthSlot0` partition.
*/
kDifOtpCtrlStatusCodePlatIntegAuthSlot0Error,
/**
* Indicates an error occurred in the `PlatIntegAuthSlot1` partition.
*/
kDifOtpCtrlStatusCodePlatIntegAuthSlot1Error,
/**
* Indicates an error occurred in the `PlatOwnerAuthSlot0` partition.
*/
kDifOtpCtrlStatusCodePlatOwnerAuthSlot0Error,
/**
* Indicates an error occurred in the `PlatOwnerAuthSlot1` partition.
*/
kDifOtpCtrlStatusCodePlatOwnerAuthSlot1Error,
/**
* Indicates an error occurred in the `PlatOwnerAuthSlot2` partition.
*/
kDifOtpCtrlStatusCodePlatOwnerAuthSlot2Error,
/**
* Indicates an error occurred in the `PlatOwnerAuthSlot3` partition.
*/
kDifOtpCtrlStatusCodePlatOwnerAuthSlot3Error,
/**
* Indicates an error occurred in the `ExtNvm` partition.
*/
kDifOtpCtrlStatusCodeExtNvmError,
/**
* Indicates an error occurred in the `RomPatch` partition.
*/
kDifOtpCtrlStatusCodeRomPatchError,
#else
#error "dif_otp_ctrl does not support this top"
#endif
/**
* Indicates an error occurred in the `HwCfg0` partition.
*/
Expand All @@ -210,6 +360,16 @@ typedef enum dif_otp_ctrl_status_code {
* Indicates an error occurred in the `Secret2` partition.
*/
kDifOtpCtrlStatusCodeSecret2Error,
#if defined(OPENTITAN_IS_DARJEELING)
/**
* Indicates an error occurred in the `Secret3` partition.
*/
kDifOtpCtrlStatusCodeSecret3Error,
#elif defined(OPENTITAN_IS_EARLGREY)
// Earlgrey only has 3 secret partitions.
#else
#error "dif_otp_ctrl does not support this top"
#endif
/**
* Indicates an error occurred in the `LifeCycle` partition.
*/
Expand Down
23 changes: 23 additions & 0 deletions sw/device/lib/testing/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -588,3 +588,26 @@ cc_library(
"//sw/device/lib/testing/test_framework:check",
],
)

cc_library(
name = "keymgr_dpe_testutils",
srcs = ["keymgr_dpe_testutils.c"],
hdrs = ["keymgr_dpe_testutils.h"],
target_compatible_with = [OPENTITAN_CPU],
deps = [
":entropy_testutils",
":kmac_testutils",
":otp_ctrl_testutils",
":rstmgr_testutils",
"//hw/top:dt",
"//hw/top:keymgr_dpe_c_regs",
"//sw/device/lib/arch:boot_stage",
"//sw/device/lib/base:mmio",
"//sw/device/lib/dif:keymgr_dpe",
"//sw/device/lib/dif:otp_ctrl",
"//sw/device/lib/dif:rstmgr",
"//sw/device/lib/runtime:ibex",
"//sw/device/lib/testing/test_framework:check",
"//sw/device/silicon_creator/lib/base:chip",
],
)
111 changes: 111 additions & 0 deletions sw/device/lib/testing/keymgr_dpe_testutils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/lib/testing/keymgr_dpe_testutils.h"

#include "dt/dt_keymgr_dpe.h"
#include "dt/dt_otp_ctrl.h"
#include "dt/dt_rstmgr.h"
#include "sw/device/lib/dif/dif_keymgr_dpe.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/otp_ctrl_testutils.h"
#include "sw/device/lib/testing/rstmgr_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/silicon_creator/lib/base/chip.h"

status_t keymgr_dpe_testutils_startup(dif_keymgr_dpe_t *keymgr_dpe,
uint32_t slot_dst_sel) {
dif_rstmgr_t rstmgr;
dif_rstmgr_reset_info_bitfield_t info;

TRY(dif_rstmgr_init_from_dt(kDtRstmgrAon, &rstmgr));
info = rstmgr_testutils_reason_get();

// POR reset.
if (info == kDifRstmgrResetInfoPor) {
LOG_INFO(
"Powered up for the first time, lock SECRET2 and SECRET3 partitions");
dif_otp_ctrl_t otp;
TRY(dif_otp_ctrl_init_from_dt(kDtOtpCtrl, &otp));
TRY(otp_ctrl_testutils_lock_partition(&otp, kDifOtpCtrlPartitionSecret2,
0));
TRY(otp_ctrl_testutils_lock_partition(&otp, kDifOtpCtrlPartitionSecret3,
0));

// Reboot device.
rstmgr_testutils_reason_clear();
LOG_INFO("Triggering software reset");
TRY(dif_rstmgr_software_device_reset(&rstmgr));

// Wait here until device reset.
wait_for_interrupt();

} else {
TRY_CHECK(info == kDifRstmgrResetInfoSw, "Unexpected reset reason: %08x",
info);
LOG_INFO(
"Powered up for the second time, actuate keymgr_dpe and perform test.");

// Initialize keymgr_dpe context.
TRY(dif_keymgr_dpe_init_from_dt(kDtKeymgrDpe, keymgr_dpe));

// Advance to Initialized state.
TRY(keymgr_dpe_testutils_check_state(keymgr_dpe, kDifKeymgrDpeStateReset));
TRY(dif_keymgr_dpe_initialize(keymgr_dpe, slot_dst_sel));
TRY(keymgr_dpe_testutils_wait_for_operation_done(keymgr_dpe));
TRY(keymgr_dpe_testutils_check_state(keymgr_dpe,
kDifKeymgrDpeStateAvailable));
LOG_INFO("UDS is latched.");
}
return OK_STATUS();
}

status_t keymgr_dpe_testutils_advance_state(
const dif_keymgr_dpe_t *keymgr_dpe,
const dif_keymgr_dpe_advance_params_t *params) {
TRY(dif_keymgr_dpe_advance_state(keymgr_dpe, params));
return keymgr_dpe_testutils_wait_for_operation_done(keymgr_dpe);
}

status_t keymgr_dpe_testutils_erase_slot(
const dif_keymgr_dpe_t *keymgr_dpe,
const dif_keymgr_dpe_erase_params_t *params) {
TRY(dif_keymgr_dpe_erase_slot(keymgr_dpe, params));
return keymgr_dpe_testutils_wait_for_operation_done(keymgr_dpe);
}

status_t keymgr_dpe_testutils_generate(
const dif_keymgr_dpe_t *keymgr_dpe,
const dif_keymgr_dpe_generate_params_t *params,
dif_keymgr_dpe_output_t *key) {
TRY(dif_keymgr_dpe_generate(keymgr_dpe, params));
TRY(keymgr_dpe_testutils_wait_for_operation_done(keymgr_dpe));
TRY(dif_keymgr_dpe_read_output(keymgr_dpe, key));
return OK_STATUS();
}

status_t keymgr_dpe_testutils_check_state(
const dif_keymgr_dpe_t *keymgr_dpe,
const dif_keymgr_dpe_state_t exp_state) {
dif_keymgr_dpe_state_t act_state;
TRY(dif_keymgr_dpe_get_state(keymgr_dpe, &act_state));
TRY_CHECK(act_state == exp_state,
"KeymgrDPE in unexpected state: %x, expected to be %x", act_state,
exp_state);
return OK_STATUS();
}

status_t keymgr_dpe_testutils_wait_for_operation_done(
const dif_keymgr_dpe_t *keymgr_dpe) {
dif_keymgr_dpe_status_codes_t status;
do {
TRY(dif_keymgr_dpe_get_status_codes(keymgr_dpe, &status));
} while (status == 0);
TRY_CHECK(status == kDifKeymgrDpeStatusCodeIdle, "Unexpected status: %x",
status);
return OK_STATUS();
}
Loading
Loading