[test] Add KMAC sideloading test.
Add a test from the test plan that sideloads a key to KMAC. For now, all
it does is check that the software key isn't used.
Signed-off-by: Jade Philipoom <jadep@google.com>
diff --git a/hw/top_earlgrey/data/chip_testplan.hjson b/hw/top_earlgrey/data/chip_testplan.hjson
index f0565b8..a28f118 100644
--- a/hw/top_earlgrey/data/chip_testplan.hjson
+++ b/hw/top_earlgrey/data/chip_testplan.hjson
@@ -2118,7 +2118,7 @@
X-ref'ed with chip_kmac_app_keymgr test.
'''
milestone: V2
- tests: []
+ tests: ["chip_sw_keymgr_sideload_kmac"]
}
{
name: chip_sw_keymgr_sideload_aes
diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
index e082f71..6a81546 100644
--- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson
+++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
@@ -846,6 +846,13 @@
run_opts: ["+sw_test_timeout_ns=20_000_000", "+en_jitter=1"]
}
{
+ name: chip_sw_keymgr_sideload_kmac
+ uvm_test_seq: chip_sw_base_vseq
+ sw_images: ["//sw/device/tests/sim_dv:keymgr_sideload_kmac_test:1"]
+ en_run_modes: ["sw_test_mode_test_rom"]
+ run_opts: ["+sw_test_timeout_ns=20_000_000"]
+ }
+ {
name: chip_sw_kmac_mode_cshake
uvm_test_seq: chip_sw_base_vseq
sw_images: ["//sw/device/tests:kmac_mode_cshake_test:1"]
diff --git a/sw/device/lib/testing/BUILD b/sw/device/lib/testing/BUILD
index 8630dbd..96f6068 100644
--- a/sw/device/lib/testing/BUILD
+++ b/sw/device/lib/testing/BUILD
@@ -156,8 +156,24 @@
"//sw/device/lib/base:mmio",
"//sw/device/lib/dif:flash_ctrl",
"//sw/device/lib/dif:keymgr",
+ "//sw/device/lib/dif:otp_ctrl",
+ "//sw/device/lib/dif:rstmgr",
"//sw/device/lib/runtime:ibex",
"//sw/device/lib/testing:flash_ctrl_testutils",
+ "//sw/device/lib/testing:kmac_testutils",
+ "//sw/device/lib/testing:otp_ctrl_testutils",
+ "//sw/device/lib/testing:rstmgr_testutils",
+ "//sw/device/lib/testing/test_framework:check",
+ ],
+)
+
+cc_library(
+ name = "kmac_testutils",
+ srcs = ["kmac_testutils.c"],
+ hdrs = ["kmac_testutils.h"],
+ target_compatible_with = [OPENTITAN_CPU],
+ deps = [
+ "//sw/device/lib/dif:kmac",
"//sw/device/lib/testing/test_framework:check",
],
)
diff --git a/sw/device/lib/testing/keymgr_testutils.c b/sw/device/lib/testing/keymgr_testutils.c
index c7cc57b..1763202 100644
--- a/sw/device/lib/testing/keymgr_testutils.c
+++ b/sw/device/lib/testing/keymgr_testutils.c
@@ -6,9 +6,15 @@
#include "sw/device/lib/dif/dif_flash_ctrl.h"
#include "sw/device/lib/dif/dif_keymgr.h"
+#include "sw/device/lib/dif/dif_kmac.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/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/kmac_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 "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
@@ -61,7 +67,7 @@
CHECK_ARRAYS_EQ(data, readback_data, kSecretWordSize);
}
-void keymgr_testutils_init_flash(void) {
+static void init_flash(void) {
dif_flash_ctrl_state_t flash;
CHECK_DIF_OK(dif_flash_ctrl_init_state(
@@ -72,6 +78,64 @@
write_info_page(&flash, kFlashInfoPageIdOwnerSecret, kOwnerSecret);
}
+void keymgr_testutils_startup(dif_keymgr_t *keymgr, dif_kmac_t *kmac) {
+ dif_rstmgr_t rstmgr;
+ dif_rstmgr_reset_info_bitfield_t info;
+
+ CHECK_DIF_OK(dif_rstmgr_init(
+ mmio_region_from_addr(TOP_EARLGREY_RSTMGR_AON_BASE_ADDR), &rstmgr));
+ info = rstmgr_testutils_reason_get();
+
+ // POR reset.
+ if (info == kDifRstmgrResetInfoPor) {
+ LOG_INFO("Powered up for the first time, program flash");
+
+ init_flash();
+
+ // Lock otp secret partition.
+ dif_otp_ctrl_t otp;
+ CHECK_DIF_OK(dif_otp_ctrl_init(
+ mmio_region_from_addr(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR), &otp));
+ otp_ctrl_testutils_lock_partition(&otp, kDifOtpCtrlPartitionSecret2, 0);
+
+ // Reboot device.
+ rstmgr_testutils_reason_clear();
+ CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+
+ // Wait here until device reset.
+ wait_for_interrupt();
+
+ } else {
+ CHECK(info == kDifRstmgrResetInfoSw, "Unexpected reset reason: %0x", info);
+ LOG_INFO(
+ "Powered up for the second time, actuate keymgr and perform test.");
+
+ // Initialize KMAC in preparation for keymgr use.
+ CHECK_DIF_OK(dif_kmac_init(
+ mmio_region_from_addr(TOP_EARLGREY_KMAC_BASE_ADDR), kmac));
+
+ // We shouldn't use the KMAC block's default entropy setting for keymgr, so
+ // configure it to use software entropy (and a sideloaded key, although it
+ // shouldn't matter here and tests should reconfigure if needed).
+ kmac_testutils_config(kmac, true);
+
+ // Initialize keymgr context.
+ CHECK_DIF_OK(dif_keymgr_init(
+ mmio_region_from_addr(TOP_EARLGREY_KEYMGR_BASE_ADDR), keymgr));
+
+ // Advance to Initialized state.
+ keymgr_testutils_check_state(keymgr, kDifKeymgrStateReset);
+ keymgr_testutils_advance_state(keymgr, NULL);
+ keymgr_testutils_check_state(keymgr, kDifKeymgrStateInitialized);
+ LOG_INFO("Keymgr entered Init State");
+
+ // Advance to CreatorRootKey state.
+ keymgr_testutils_advance_state(keymgr, &kCreatorParams);
+ keymgr_testutils_check_state(keymgr, kDifKeymgrStateCreatorRootKey);
+ LOG_INFO("Keymgr entered CreatorRootKey State");
+ }
+}
+
void keymgr_testutils_advance_state(const dif_keymgr_t *keymgr,
const dif_keymgr_state_params_t *params) {
CHECK_DIF_OK(dif_keymgr_advance_state(keymgr, params));
diff --git a/sw/device/lib/testing/keymgr_testutils.h b/sw/device/lib/testing/keymgr_testutils.h
index 20132ce..b88974d 100644
--- a/sw/device/lib/testing/keymgr_testutils.h
+++ b/sw/device/lib/testing/keymgr_testutils.h
@@ -6,6 +6,7 @@
#define OPENTITAN_SW_DEVICE_LIB_TESTING_KEYMGR_TESTUTILS_H_
#include "sw/device/lib/dif/dif_keymgr.h"
+#include "sw/device/lib/dif/dif_kmac.h"
/**
* Versioned key parameters for testing.
@@ -47,9 +48,31 @@
};
/**
- * Initialize flash for key manager operation.
+ * Programs flash, restarts, and advances keymgr to CreatorRootKey state.
+ *
+ * This procedure essentially gets the keymgr into the first state where it can
+ * be used for tests. Tests should call it before anything else, like below:
+ *
+ * void test_main(void) {
+ * // Set up and advance to CreatorRootKey state.
+ * dif_keymgr_t keymgr;
+ * dif_kmac_t kmac;
+ * keymgr_testutils_startup(&keymgr, &kmac);
+ *
+ * // Remainder of test; optionally advance to OwnerIntKey state, generate
+ * // keys and identities.
+ * ...
+ * }
+ *
+ * Because the key manager uses KMAC, this procedure also initializes and
+ * configures KMAC. Software should not rely on the configuration here and
+ * should reconfigure KMAC if needed. The purpose of configuring KMAC in this
+ * procedure is so that the key manager will not use KMAC with the default
+ * entropy settings.
+ *
+ * @param keymgr A key manager handle.
*/
-void keymgr_testutils_init_flash(void);
+void keymgr_testutils_startup(dif_keymgr_t *keymgr, dif_kmac_t *kmac);
/**
* Issues a keymgr advance operation and wait for it to complete
diff --git a/sw/device/lib/testing/kmac_testutils.c b/sw/device/lib/testing/kmac_testutils.c
new file mode 100644
index 0000000..fc17dab
--- /dev/null
+++ b/sw/device/lib/testing/kmac_testutils.c
@@ -0,0 +1,66 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "sw/device/lib/testing/kmac_testutils.h"
+
+#include "sw/device/lib/dif/dif_kmac.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+
+void kmac_testutils_config(dif_kmac_t *kmac, bool sideload) {
+ dif_kmac_config_t config = {
+ // Use software-provided "entropy" to avoid waiting for EDN.
+ .entropy_mode = kDifKmacEntropyModeSoftware,
+ // This option minimizes masking to improve speed.
+ .entropy_fast_process = true,
+ // No need to have real entropy for tests.
+ .entropy_seed = {0},
+ // Ignored because the entropy source is software.
+ .entropy_reseed_interval = 0,
+ // Ignored because the entropy source is software.
+ .entropy_wait_timer = 0,
+ // Leave message as the little-endian default.
+ .message_big_endian = false,
+ // Leave output as the little-endian default.
+ .output_big_endian = false,
+ // Use a sideloaded key if the caller requested to.
+ .sideload = sideload,
+ // Avoid masking the message to improve speed.
+ .msg_mask = false,
+ };
+
+ CHECK_DIF_OK(dif_kmac_configure(kmac, config));
+}
+
+void kmac_testutils_kmac(const dif_kmac_t *kmac,
+ const dif_kmac_mode_kmac_t mode,
+ const dif_kmac_key_t *key, const char *custom_string,
+ const size_t custom_string_len, const char *message,
+ const size_t message_len, const size_t output_len,
+ uint32_t *output) {
+ // Initialize customization string.
+ dif_kmac_customization_string_t kmac_custom_string;
+ CHECK_DIF_OK(dif_kmac_customization_string_init(
+ custom_string, custom_string_len, &kmac_custom_string));
+
+ // Start the KMAC operation.
+ dif_kmac_operation_state_t operation_state;
+ CHECK_DIF_OK(dif_kmac_mode_kmac_start(kmac, &operation_state, mode,
+ output_len, key, &kmac_custom_string));
+
+ // Pass the entire message to KMAC ("absorb" stage).
+ CHECK_DIF_OK(
+ dif_kmac_absorb(kmac, &operation_state, message, message_len, NULL));
+
+ // Get the output ("squeeze" stage).
+ CHECK_DIF_OK(
+ dif_kmac_squeeze(kmac, &operation_state, output, output_len, NULL));
+
+ // End the operation.
+ CHECK_DIF_OK(dif_kmac_end(kmac, &operation_state));
+
+ // Double-check that there were no errors.
+ dif_kmac_error_t err;
+ CHECK_DIF_OK(dif_kmac_get_error(kmac, &err));
+ CHECK(err == kDifErrorNone);
+}
diff --git a/sw/device/lib/testing/kmac_testutils.h b/sw/device/lib/testing/kmac_testutils.h
new file mode 100644
index 0000000..b5f4d00
--- /dev/null
+++ b/sw/device/lib/testing/kmac_testutils.h
@@ -0,0 +1,45 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_KMAC_TESTUTILS_H_
+#define OPENTITAN_SW_DEVICE_LIB_TESTING_KMAC_TESTUTILS_H_
+
+#include "sw/device/lib/dif/dif_kmac.h"
+
+/**
+ * Configure the KMAC block.
+ *
+ * This is a thin wrapper around `dif_kmac_configure`. It sets up a testing
+ * configuration that prioritizes speed over security, since we don't care
+ * about protecting test keys. For instance, it sets the entropy source to
+ * software so KMAC doesn't wait for fresh entropy, and minimizes masking.
+ *
+ * @param kmac KMAC context
+ * @param sideload Whether to configure KMAC to read a sideloaded key.
+ */
+void kmac_testutils_config(dif_kmac_t *kmac, bool sideload);
+
+/**
+ * Runs the full KMAC operation.
+ *
+ * Assumes that the KMAC block has already been initialized and configured, and
+ * that the sideloaded key has been loaded (if applicable).
+ *
+ * @param kmac KMAC block context
+ * @param mode Mode (security strength) for KMAC
+ * @param key KMAC key
+ * @param custom_string Customization string
+ * @param custom_string_len Length of customization string
+ * @param message Input message
+ * @param message_len Length of message in bytes
+ * @param output_len Requested length of output in words
+ * @param output Pre-allocated output buffer (length must match output_len)
+ */
+void kmac_testutils_kmac(const dif_kmac_t *kmac, dif_kmac_mode_kmac_t mode,
+ const dif_kmac_key_t *key, const char *custom_string,
+ const size_t custom_string_len, const char *message,
+ const size_t message_len, const size_t output_len,
+ uint32_t *output);
+
+#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_KMAC_TESTUTILS_H_
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD
index 7f58a7e..e658757 100644
--- a/sw/device/tests/BUILD
+++ b/sw/device/tests/BUILD
@@ -55,15 +55,10 @@
"//sw/device/lib/base:mmio",
"//sw/device/lib/dif:aes",
"//sw/device/lib/dif:keymgr",
- "//sw/device/lib/dif:kmac",
- "//sw/device/lib/dif:otp_ctrl",
- "//sw/device/lib/dif:rstmgr",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:aes_testutils",
"//sw/device/lib/testing:entropy_testutils",
"//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_main",
],
)
diff --git a/sw/device/tests/aes_sideload_test.c b/sw/device/tests/aes_sideload_test.c
index cfcbe50..d88eead 100644
--- a/sw/device/tests/aes_sideload_test.c
+++ b/sw/device/tests/aes_sideload_test.c
@@ -7,14 +7,11 @@
#include "sw/device/lib/dif/dif_aes.h"
#include "sw/device/lib/dif/dif_keymgr.h"
#include "sw/device/lib/dif/dif_kmac.h"
-#include "sw/device/lib/dif/dif_otp_ctrl.h"
-#include "sw/device/lib/dif/dif_rstmgr.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/aes_testutils.h"
#include "sw/device/lib/testing/entropy_testutils.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/kmac_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"
@@ -30,37 +27,18 @@
0xffeeddcc,
};
static dif_keymgr_t keymgr;
+static dif_kmac_t kmac;
OTTF_DEFINE_TEST_CONFIG();
static void keymgr_initialize(void) {
- mmio_region_t base_addr =
- mmio_region_from_addr(TOP_EARLGREY_KEYMGR_BASE_ADDR);
- CHECK_DIF_OK(dif_keymgr_init(base_addr, &keymgr));
-
- keymgr_testutils_check_state(&keymgr, kDifKeymgrStateReset);
-
- keymgr_testutils_advance_state(&keymgr, NULL);
- keymgr_testutils_check_state(&keymgr, kDifKeymgrStateInitialized);
- LOG_INFO("Keymgr entered Init State");
-
- keymgr_testutils_advance_state(&keymgr, &kCreatorParams);
- keymgr_testutils_check_state(&keymgr, kDifKeymgrStateCreatorRootKey);
- LOG_INFO("Keymgr entered CreatorRootKey State");
-
- keymgr_testutils_generate_identity(&keymgr);
- LOG_INFO("Keymgr generated identity at CreatorRootKey State");
+ // Initialize keymgr and advance to CreatorRootKey state.
+ keymgr_testutils_startup(&keymgr, &kmac);
keymgr_testutils_advance_state(&keymgr, &kOwnerIntParams);
keymgr_testutils_check_state(&keymgr, kDifKeymgrStateOwnerIntermediateKey);
LOG_INFO("Keymgr entered OwnerIntKey State");
- keymgr_testutils_generate_identity(&keymgr);
- LOG_INFO("Keymgr generated identity at OwnerIntKey State");
-
- keymgr_testutils_generate_versioned_key(&keymgr, kKeyVersionedParams);
- LOG_INFO("Keymgr generated SW output at OwnerIntKey State");
-
dif_keymgr_versioned_key_params_t sideload_params = kKeyVersionedParams;
sideload_params.dest = kDifKeymgrVersionedKeyDestAes;
keymgr_testutils_generate_versioned_key(&keymgr, sideload_params);
@@ -143,42 +121,11 @@
}
bool test_main(void) {
- dif_rstmgr_t rstmgr;
- dif_rstmgr_reset_info_bitfield_t info;
+ // Configure the keymgr to generate an AES key.
+ keymgr_initialize();
- CHECK_DIF_OK(dif_rstmgr_init(
- mmio_region_from_addr(TOP_EARLGREY_RSTMGR_AON_BASE_ADDR), &rstmgr));
- info = rstmgr_testutils_reason_get();
+ // Run the AES test.
+ aes_test();
- // POR reset.
- if (info == kDifRstmgrResetInfoPor) {
- LOG_INFO("Powered up for the first time, program flash");
-
- keymgr_testutils_init_flash();
-
- // Lock otp secret partition.
- dif_otp_ctrl_t otp;
- CHECK_DIF_OK(dif_otp_ctrl_init(
- mmio_region_from_addr(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR), &otp));
- otp_ctrl_testutils_lock_partition(&otp, kDifOtpCtrlPartitionSecret2, 0);
-
- // Reboot device.
- rstmgr_testutils_reason_clear();
- CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
-
- // Wait here until device reset.
- wait_for_interrupt();
-
- } else if (info == kDifRstmgrResetInfoSw) {
- LOG_INFO(
- "Powered up for the second time, actuate keymgr and perform aes test.");
-
- // Configure the keymgr to generate an aes key.
- keymgr_initialize();
-
- aes_test();
- return true;
- }
-
- return false;
+ return true;
}
diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD
index 5e6e0f5..dd6f152 100644
--- a/sw/device/tests/sim_dv/BUILD
+++ b/sw/device/tests/sim_dv/BUILD
@@ -181,14 +181,30 @@
"//sw/device/lib/base:macros",
"//sw/device/lib/dif:keymgr",
"//sw/device/lib/dif:kmac",
- "//sw/device/lib/dif:otp_ctrl",
- "//sw/device/lib/dif:rstmgr",
"//sw/device/lib/runtime:hart",
"//sw/device/lib/runtime:log",
"//sw/device/lib/runtime:print",
"//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_main",
+ ],
+)
+
+opentitan_functest(
+ name = "keymgr_sideload_kmac_test",
+ srcs = ["keymgr_sideload_kmac_test.c"],
+ targets = ["dv"],
+ deps = [
+ "//hw/ip/keymgr/data:keymgr_regs",
+ "//hw/ip/kmac/data:kmac_regs",
+ "//sw/device/lib/arch:device",
+ "//sw/device/lib/base:macros",
+ "//sw/device/lib/dif:keymgr",
+ "//sw/device/lib/dif:kmac",
+ "//sw/device/lib/runtime:hart",
+ "//sw/device/lib/runtime:log",
+ "//sw/device/lib/runtime:print",
+ "//sw/device/lib/testing:keymgr_testutils",
+ "//sw/device/lib/testing:kmac_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
],
)
diff --git a/sw/device/tests/sim_dv/keymgr_key_derivation_test.c b/sw/device/tests/sim_dv/keymgr_key_derivation_test.c
index 47a7aca..110fa84 100644
--- a/sw/device/tests/sim_dv/keymgr_key_derivation_test.c
+++ b/sw/device/tests/sim_dv/keymgr_key_derivation_test.c
@@ -15,6 +15,7 @@
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/runtime/print.h"
#include "sw/device/lib/testing/keymgr_testutils.h"
+#include "sw/device/lib/testing/kmac_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"
@@ -26,103 +27,42 @@
OTTF_DEFINE_TEST_CONFIG();
-/** Place kmac into sideload mode for correct keymgr operation */
-static void init_kmac_for_keymgr(void) {
- dif_kmac_t kmac;
- CHECK_DIF_OK(
- dif_kmac_init(mmio_region_from_addr(TOP_EARLGREY_KMAC_BASE_ADDR), &kmac));
-
- // Configure KMAC hardware using software entropy.
- dif_kmac_config_t config = (dif_kmac_config_t){
- .entropy_mode = kDifKmacEntropyModeSoftware,
- .sideload = true,
- };
- CHECK_DIF_OK(dif_kmac_configure(&kmac, config));
-}
-
bool test_main(void) {
- dif_rstmgr_t rstmgr;
- dif_rstmgr_reset_info_bitfield_t info;
+ // Initialize keymgr and advance to CreatorRootKey state.
+ dif_keymgr_t keymgr;
+ dif_kmac_t kmac;
+ keymgr_testutils_startup(&keymgr, &kmac);
- // Initialize pwrmgr
- CHECK_DIF_OK(dif_rstmgr_init(
- mmio_region_from_addr(TOP_EARLGREY_RSTMGR_AON_BASE_ADDR), &rstmgr));
- info = rstmgr_testutils_reason_get();
+ keymgr_testutils_generate_identity(&keymgr);
+ LOG_INFO("Keymgr generated identity at CreatorRootKey State");
- // POR reset
- if (info == kDifRstmgrResetInfoPor) {
- LOG_INFO("Powered up for the first time, program flash");
+ keymgr_testutils_advance_state(&keymgr, &kOwnerIntParams);
+ keymgr_testutils_check_state(&keymgr, kDifKeymgrStateOwnerIntermediateKey);
+ LOG_INFO("Keymgr entered OwnerIntKey State");
- // Initialize flash
- keymgr_testutils_init_flash();
+ keymgr_testutils_generate_identity(&keymgr);
+ LOG_INFO("Keymgr generated identity at OwnerIntKey State");
- // Lock otp secret partition
- dif_otp_ctrl_t otp;
- CHECK_DIF_OK(dif_otp_ctrl_init(
- mmio_region_from_addr(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR), &otp));
- otp_ctrl_testutils_lock_partition(&otp, kDifOtpCtrlPartitionSecret2, 0);
+ keymgr_testutils_generate_versioned_key(&keymgr, kKeyVersionedParams);
+ LOG_INFO("Keymgr generated SW output at OwnerIntKey State");
- // reboot device
- rstmgr_testutils_reason_clear();
- CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+ // Generate sideload keys for 3 HW interfaces - Kmac, Aes, Otbn.
+ dif_keymgr_versioned_key_params_t sideload_params = kKeyVersionedParams;
+ sideload_params.dest = kDifKeymgrVersionedKeyDestKmac;
+ keymgr_testutils_generate_versioned_key(&keymgr, sideload_params);
+ LOG_INFO("Keymgr generated HW output for Kmac at OwnerIntKey State");
- // wait here until device reset
- wait_for_interrupt();
+ sideload_params.dest = kDifKeymgrVersionedKeyDestAes;
+ keymgr_testutils_generate_versioned_key(&keymgr, sideload_params);
+ LOG_INFO("Keymgr generated HW output for Aes at OwnerIntKey State");
- } else if (info == kDifRstmgrResetInfoSw) {
- LOG_INFO("Powered up for the second time, actuate keymgr");
+ sideload_params.dest = kDifKeymgrVersionedKeyDestOtbn;
+ keymgr_testutils_generate_versioned_key(&keymgr, sideload_params);
+ LOG_INFO("Keymgr generated HW output for Otbn at OwnerIntKey State");
- init_kmac_for_keymgr();
+ keymgr_testutils_disable(&keymgr);
+ keymgr_testutils_check_state(&keymgr, kDifKeymgrStateDisabled);
+ LOG_INFO("Keymgr entered Disabled state");
- dif_keymgr_t keymgr;
- CHECK_DIF_OK(dif_keymgr_init(
- mmio_region_from_addr(TOP_EARLGREY_KEYMGR_BASE_ADDR), &keymgr));
-
- keymgr_testutils_check_state(&keymgr, kDifKeymgrStateReset);
-
- keymgr_testutils_advance_state(&keymgr, NULL);
- keymgr_testutils_check_state(&keymgr, kDifKeymgrStateInitialized);
- LOG_INFO("Keymgr entered Init State");
-
- keymgr_testutils_advance_state(&keymgr, &kCreatorParams);
- keymgr_testutils_check_state(&keymgr, kDifKeymgrStateCreatorRootKey);
- LOG_INFO("Keymgr entered CreatorRootKey State");
-
- keymgr_testutils_generate_identity(&keymgr);
- LOG_INFO("Keymgr generated identity at CreatorRootKey State");
-
- keymgr_testutils_advance_state(&keymgr, &kOwnerIntParams);
- keymgr_testutils_check_state(&keymgr, kDifKeymgrStateOwnerIntermediateKey);
- LOG_INFO("Keymgr entered OwnerIntKey State");
-
- keymgr_testutils_generate_identity(&keymgr);
- LOG_INFO("Keymgr generated identity at OwnerIntKey State");
-
- keymgr_testutils_generate_versioned_key(&keymgr, kKeyVersionedParams);
- LOG_INFO("Keymgr generated SW output at OwnerIntKey State");
-
- // Generate sideload keys for 3 HW interfaces - Kmac, Aes, Otbn.
- dif_keymgr_versioned_key_params_t sideload_params = kKeyVersionedParams;
- sideload_params.dest = kDifKeymgrVersionedKeyDestKmac;
- keymgr_testutils_generate_versioned_key(&keymgr, sideload_params);
- LOG_INFO("Keymgr generated HW output for Kmac at OwnerIntKey State");
-
- sideload_params.dest = kDifKeymgrVersionedKeyDestAes;
- keymgr_testutils_generate_versioned_key(&keymgr, sideload_params);
- LOG_INFO("Keymgr generated HW output for Aes at OwnerIntKey State");
-
- sideload_params.dest = kDifKeymgrVersionedKeyDestOtbn;
- keymgr_testutils_generate_versioned_key(&keymgr, sideload_params);
- LOG_INFO("Keymgr generated HW output for Otbn at OwnerIntKey State");
-
- keymgr_testutils_disable(&keymgr);
- keymgr_testutils_check_state(&keymgr, kDifKeymgrStateDisabled);
- LOG_INFO("Keymgr entered Disabled state");
-
- return true;
- } else {
- LOG_FATAL("Unexpected reset reason unexpected: %0x", info);
- }
-
- return false;
+ return true;
}
diff --git a/sw/device/tests/sim_dv/keymgr_sideload_kmac_test.c b/sw/device/tests/sim_dv/keymgr_sideload_kmac_test.c
new file mode 100644
index 0000000..7992df8
--- /dev/null
+++ b/sw/device/tests/sim_dv/keymgr_sideload_kmac_test.c
@@ -0,0 +1,108 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "sw/device/lib/arch/device.h"
+#include "sw/device/lib/base/macros.h"
+#include "sw/device/lib/dif/dif_keymgr.h"
+#include "sw/device/lib/dif/dif_kmac.h"
+#include "sw/device/lib/runtime/hart.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/runtime/print.h"
+#include "sw/device/lib/testing/keymgr_testutils.h"
+#include "sw/device/lib/testing/kmac_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
+#include "keymgr_regs.h" // Generated.
+#include "kmac_regs.h" // Generated.
+
+// The KMAC dif expects a secret key, even though if the configuration is set
+// to use the sideloaded key then it will be ignored. We will write a software
+// key and then ensure that the output does NOT match the expected value for
+// this key when sideloading is used.
+//
+// Test taken from sample #1 here:
+// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/KMAC_samples.pdf
+static const dif_kmac_key_t kSoftwareKey = {
+ .share0 = {0x43424140, 0x47464544, 0x4B4A4948, 0x4F4E4D4C, 0x53525150,
+ 0x57565554, 0x5B5A5958, 0x5F5E5D5C},
+ .share1 = {0},
+ .length = kDifKmacKeyLen256,
+};
+static const dif_kmac_mode_kmac_t kKmacMode = kDifKmacModeKmacLen128;
+static const size_t kKmacOutputLen = 8;
+static const uint32_t kSoftwareKeyExpectedOutput[8] = {
+ 0x0D0B78E5, 0xD3F7A63E, 0x70C529A4, 0x003AA46A,
+ 0xD4D7DBFA, 0x9E832896, 0x3F248731, 0x4EE16E45};
+static const char *kCustomString = NULL;
+static const size_t kCustomStringLen = 0;
+static const char kKmacMessage[] = "\x00\x01\x02\x03";
+static const size_t kKmacMessageLen = 4;
+
+OTTF_DEFINE_TEST_CONFIG();
+
+/**
+ * Initialize and run KMAC using a sideloaded key.
+ *
+ * First, checks that KMAC works with the software key. Next, checks that when
+ * sideload=true, KMAC produces a different result.
+ */
+static void test_kmac_with_sideloaded_key(dif_keymgr_t *keymgr,
+ dif_kmac_t *kmac) {
+ // Configure KMAC hardware (using software key and software entropy).
+ kmac_testutils_config(kmac, false);
+
+ uint32_t output[kKmacOutputLen];
+ kmac_testutils_kmac(kmac, kKmacMode, &kSoftwareKey, kCustomString,
+ kCustomStringLen, kKmacMessage, kKmacMessageLen,
+ kKmacOutputLen, output);
+ LOG_INFO("Computed KMAC output for software key.");
+
+ // Check that the output matches the expected output.
+ CHECK_ARRAYS_EQ(output, kSoftwareKeyExpectedOutput, kKmacOutputLen);
+
+ // Reconfigure KMAC to use the sideloaded key.
+ kmac_testutils_config(kmac, true);
+
+ // Generate the sideloaded key.
+ dif_keymgr_versioned_key_params_t sideload_params = kKeyVersionedParams;
+ sideload_params.dest = kDifKeymgrVersionedKeyDestKmac;
+ keymgr_testutils_generate_versioned_key(keymgr, sideload_params);
+ LOG_INFO("Keymgr generated HW output for KMAC.");
+
+ kmac_testutils_kmac(kmac, kKmacMode, &kSoftwareKey, kCustomString,
+ kCustomStringLen, kKmacMessage, kKmacMessageLen,
+ kKmacOutputLen, output);
+ LOG_INFO("Computed KMAC output for sideloaded key.");
+
+ // Check that the output is different from the software key output
+ // (indicating the software key was not used).
+ //
+ // TODO(weicai): also check in SV sequence that the KMAC output is correct.
+ CHECK_ARRAYS_NE(output, kSoftwareKeyExpectedOutput, kKmacOutputLen);
+}
+
+bool test_main(void) {
+ // Initialize keymgr and advance to CreatorRootKey state.
+ dif_keymgr_t keymgr;
+ dif_kmac_t kmac;
+ keymgr_testutils_startup(&keymgr, &kmac);
+
+ // Test KMAC sideloading.
+ test_kmac_with_sideloaded_key(&keymgr, &kmac);
+
+ // Advance to OwnerIntKey state.
+ keymgr_testutils_advance_state(&keymgr, &kOwnerIntParams);
+ keymgr_testutils_check_state(&keymgr, kDifKeymgrStateOwnerIntermediateKey);
+ LOG_INFO("Keymgr entered OwnerIntKey State");
+
+ // Test KMAC sideloading.
+ test_kmac_with_sideloaded_key(&keymgr, &kmac);
+
+ return true;
+}