From c97c3c6f5ae5ca03084ca770d30737708e9deb34 Mon Sep 17 00:00:00 2001 From: Yi-Hsuan Deng Date: Thu, 21 Nov 2024 13:53:35 +0000 Subject: [PATCH] [imm_rom_ext] Mint CDI_0 certs in immutable rom ext Since CDI_0 attests the integrity of rom_ext, this PR moves the UDS & CDI_0 stage to the immutable rom_ext part, which will be executed before mutable rom_ext, to establish root trust in hardware. SKU owners can choose whether the immutability should be enforced using the `CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN` OTP field. Change-Id: If971654a27ea32eaf74d20d385e48801d28e1da5 Signed-off-by: Yi-Hsuan Deng --- sw/device/silicon_creator/imm_rom_ext/BUILD | 19 ++++++ .../silicon_creator/imm_rom_ext/e2e/BUILD | 10 ++++ .../imm_rom_ext/e2e/boot_message/BUILD | 26 ++++++++ .../imm_rom_ext/e2e/empty_test.c | 9 +++ .../silicon_creator/imm_rom_ext/imm_rom_ext.c | 59 ++++++++++++++++++- .../silicon_creator/lib/cert/dice_chain.c | 3 +- .../silicon_creator/lib/drivers/pinmux.c | 2 + .../silicon_creator/lib/drivers/pinmux.h | 5 ++ .../lib/drivers/pinmux_unittest.cc | 8 +++ .../rom/e2e/address_translation/BUILD | 21 ++++--- sw/device/silicon_creator/rom/e2e/defs.bzl | 3 +- sw/device/silicon_creator/rom_ext/BUILD | 15 +++++ sw/device/silicon_creator/rom_ext/rom_ext.c | 17 +----- .../rom_ext/rom_ext_manifest.c | 23 ++++++++ .../rom_ext/rom_ext_manifest.h | 25 ++++++++ 15 files changed, 220 insertions(+), 25 deletions(-) create mode 100644 sw/device/silicon_creator/imm_rom_ext/e2e/BUILD create mode 100644 sw/device/silicon_creator/imm_rom_ext/e2e/boot_message/BUILD create mode 100644 sw/device/silicon_creator/imm_rom_ext/e2e/empty_test.c create mode 100644 sw/device/silicon_creator/rom_ext/rom_ext_manifest.c create mode 100644 sw/device/silicon_creator/rom_ext/rom_ext_manifest.h diff --git a/sw/device/silicon_creator/imm_rom_ext/BUILD b/sw/device/silicon_creator/imm_rom_ext/BUILD index 71cf2fe68cc2a..3408523a55025 100644 --- a/sw/device/silicon_creator/imm_rom_ext/BUILD +++ b/sw/device/silicon_creator/imm_rom_ext/BUILD @@ -8,4 +8,23 @@ cc_library( name = "main_lib", srcs = ["imm_rom_ext.c"], hdrs = ["imm_rom_ext.h"], + deps = [ + "//hw/top_earlgrey/ip_autogen/flash_ctrl:flash_ctrl_c_regs", + "//sw/device/lib/arch:device", + "//sw/device/lib/base:macros", + "//sw/device/silicon_creator/lib:dbg_print", + "//sw/device/silicon_creator/lib:epmp_state", + "//sw/device/silicon_creator/lib:error", + "//sw/device/silicon_creator/lib:manifest", + "//sw/device/silicon_creator/lib:shutdown", + "//sw/device/silicon_creator/lib/base:boot_measurements", + "//sw/device/silicon_creator/lib/base:sec_mmio", + "//sw/device/silicon_creator/lib/base:static_critical", + "//sw/device/silicon_creator/lib/cert:dice_chain", + "//sw/device/silicon_creator/lib/drivers:pinmux", + "//sw/device/silicon_creator/lib/drivers:rnd", + "//sw/device/silicon_creator/lib/drivers:uart", + "//sw/device/silicon_creator/lib/ownership:ownership_key", + "//sw/device/silicon_creator/rom_ext:rom_ext_manifest", + ], ) diff --git a/sw/device/silicon_creator/imm_rom_ext/e2e/BUILD b/sw/device/silicon_creator/imm_rom_ext/e2e/BUILD new file mode 100644 index 0000000000000..74d93418a4d25 --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/e2e/BUILD @@ -0,0 +1,10 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "empty_test", + srcs = ["empty_test.c"], +) diff --git a/sw/device/silicon_creator/imm_rom_ext/e2e/boot_message/BUILD b/sw/device/silicon_creator/imm_rom_ext/e2e/boot_message/BUILD new file mode 100644 index 0000000000000..3e2a695cca0a3 --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/e2e/boot_message/BUILD @@ -0,0 +1,26 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +load( + "//rules/opentitan:defs.bzl", + "fpga_params", + "opentitan_test", +) + +package(default_visibility = ["//visibility:public"]) + +opentitan_test( + name = "boot_test", + srcs = ["//sw/device/silicon_creator/imm_rom_ext/e2e:empty_test"], + exec_env = { + "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, + }, + fpga = fpga_params( + exit_success = "\nIMM_ROM_EXT:", + ), + deps = [ + "//sw/device/lib/testing/test_framework:ottf_main", + ], +) diff --git a/sw/device/silicon_creator/imm_rom_ext/e2e/empty_test.c b/sw/device/silicon_creator/imm_rom_ext/e2e/empty_test.c new file mode 100644 index 0000000000000..4beb355c443c0 --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/e2e/empty_test.c @@ -0,0 +1,9 @@ +// 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/test_framework/ottf_main.h" + +OTTF_DEFINE_TEST_CONFIG(); + +bool test_main(void) { return true; } diff --git a/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.c b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.c index cb60eaab0521d..3f2a1b948287e 100644 --- a/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.c +++ b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.c @@ -4,7 +4,64 @@ #include "sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.h" +#include "sw/device/lib/arch/device.h" +#include "sw/device/lib/base/macros.h" +#include "sw/device/silicon_creator/lib/base/boot_measurements.h" +#include "sw/device/silicon_creator/lib/base/sec_mmio.h" +#include "sw/device/silicon_creator/lib/cert/dice_chain.h" +#include "sw/device/silicon_creator/lib/dbg_print.h" +#include "sw/device/silicon_creator/lib/drivers/pinmux.h" +#include "sw/device/silicon_creator/lib/drivers/rnd.h" +#include "sw/device/silicon_creator/lib/drivers/uart.h" +#include "sw/device/silicon_creator/lib/epmp_state.h" +#include "sw/device/silicon_creator/lib/error.h" +#include "sw/device/silicon_creator/lib/manifest.h" +#include "sw/device/silicon_creator/lib/ownership/ownership_key.h" +#include "sw/device/silicon_creator/lib/shutdown.h" +#include "sw/device/silicon_creator/rom_ext/rom_ext_manifest.h" + +OT_WARN_UNUSED_RESULT +static rom_error_t imm_rom_ext_start(void) { + // Check the ePMP state. + HARDENED_RETURN_IF_ERROR(epmp_state_check()); + // Check sec_mmio expectations. + // We don't check the counters since we don't want to tie ROM_EXT to a + // specific ROM version. + sec_mmio_check_values(rnd_uint32()); + + // Initialize Immutable ROM EXT. + sec_mmio_next_stage_init(); + // Configure UART0 as stdout. + pinmux_init_uart0_tx(); + uart_init(kUartNCOValue); + + dbg_printf("IMM_ROM_EXT v0.1\r\n"); + + // Establish our identity. + const manifest_t *rom_ext = rom_ext_manifest(); + HARDENED_RETURN_IF_ERROR(dice_chain_init()); + // TODO: Move UDS cert check to mutable ROM_EXT. + HARDENED_RETURN_IF_ERROR(dice_chain_attestation_silicon()); + + // Sideload sealing key to KMAC hw keyslot. + HARDENED_RETURN_IF_ERROR(ownership_seal_init()); + + HARDENED_RETURN_IF_ERROR( + dice_chain_attestation_creator(&boot_measurements.rom_ext, rom_ext)); + + // Write the DICE certs to flash if they have been updated. + HARDENED_RETURN_IF_ERROR(dice_chain_flush_flash()); + + return kErrorOk; +} + void imm_rom_ext_main(void) { - // TODO(opentitan#24368): Implement this. + rom_error_t error = imm_rom_ext_start(); + if (launder32(error) != kErrorOk) { + shutdown_finalize(error); + } + HARDENED_CHECK_EQ(error, kErrorOk); + + // Go back to ROM / Mutable ROM_EXT. return; } diff --git a/sw/device/silicon_creator/lib/cert/dice_chain.c b/sw/device/silicon_creator/lib/cert/dice_chain.c index 1d9e132c25fdf..dfe81f101ee66 100644 --- a/sw/device/silicon_creator/lib/cert/dice_chain.c +++ b/sw/device/silicon_creator/lib/cert/dice_chain.c @@ -357,6 +357,8 @@ rom_error_t dice_chain_attestation_creator( } dice_chain.endorsement_pubkey_id = dice_chain.subject_pubkey_id; + sc_keymgr_sw_binding_unlock_wait(); + return kErrorOk; } @@ -410,7 +412,6 @@ rom_error_t dice_chain_attestation_owner( } dice_chain.endorsement_pubkey_id = dice_chain.subject_pubkey_id; - // TODO: elimiate this call when we've fully programmed keymgr and lock it. sc_keymgr_sw_binding_unlock_wait(); return kErrorOk; diff --git a/sw/device/silicon_creator/lib/drivers/pinmux.c b/sw/device/silicon_creator/lib/drivers/pinmux.c index ed5e11c4f82ec..870890d0ec98f 100644 --- a/sw/device/silicon_creator/lib/drivers/pinmux.c +++ b/sw/device/silicon_creator/lib/drivers/pinmux.c @@ -169,6 +169,8 @@ static void configure_output(pinmux_output_t output) { output.outsel); } +void pinmux_init_uart0_tx(void) { configure_output(kOutputUart0); } + void pinmux_init(void) { uint32_t bootstrap_dis = otp_read32(OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET); diff --git a/sw/device/silicon_creator/lib/drivers/pinmux.h b/sw/device/silicon_creator/lib/drivers/pinmux.h index 117f2c3d41974..d1c10eb42743e 100644 --- a/sw/device/silicon_creator/lib/drivers/pinmux.h +++ b/sw/device/silicon_creator/lib/drivers/pinmux.h @@ -23,6 +23,11 @@ extern "C" { */ void pinmux_init(void); +/** + * Initialize the pinmux with output UART0 only. + */ +void pinmux_init_uart0_tx(void); + /** * Read the SW_STRAP value. * diff --git a/sw/device/silicon_creator/lib/drivers/pinmux_unittest.cc b/sw/device/silicon_creator/lib/drivers/pinmux_unittest.cc index 0cfe5b6528e8b..38fdd57769b04 100644 --- a/sw/device/silicon_creator/lib/drivers/pinmux_unittest.cc +++ b/sw/device/silicon_creator/lib/drivers/pinmux_unittest.cc @@ -125,5 +125,13 @@ TEST_F(InitTest, WithoutBootstrap) { pinmux_init(); } +TEST_F(InitTest, Uart0TxOnly) { + // The outputs that will be configured. + EXPECT_ABS_WRITE32(RegOutSel(kTopEarlgreyPinmuxMioOutIoc4), + kTopEarlgreyPinmuxOutselUart0Tx); + + pinmux_init_uart0_tx(); +} + } // namespace } // namespace pinmux_unittest diff --git a/sw/device/silicon_creator/rom/e2e/address_translation/BUILD b/sw/device/silicon_creator/rom/e2e/address_translation/BUILD index 954ae9d1ae1a4..6c1cb076636a2 100644 --- a/sw/device/silicon_creator/rom/e2e/address_translation/BUILD +++ b/sw/device/silicon_creator/rom/e2e/address_translation/BUILD @@ -26,7 +26,8 @@ package(default_visibility = ["//visibility:public"]) opentitan_test( name = "rom_ext_a_flash_a", exec_env = { - "//hw/top_earlgrey:fpga_cw310_rom_with_fake_keys": None, + "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( assemble = "{firmware}@{offset}", @@ -42,7 +43,8 @@ opentitan_test( opentitan_test( name = "rom_ext_b_flash_b", exec_env = { - "//hw/top_earlgrey:fpga_cw310_rom_with_fake_keys": None, + "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( assemble = "{firmware}@{offset}", @@ -58,7 +60,8 @@ opentitan_test( opentitan_test( name = "rom_ext_a_flash_b", exec_env = { - "//hw/top_earlgrey:fpga_cw310_rom_with_fake_keys": None, + "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( assemble = "{firmware}@{offset}", @@ -74,7 +77,8 @@ opentitan_test( opentitan_test( name = "rom_ext_b_flash_a", exec_env = { - "//hw/top_earlgrey:fpga_cw310_rom_with_fake_keys": None, + "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( assemble = "{firmware}@{offset}", @@ -90,7 +94,8 @@ opentitan_test( opentitan_test( name = "rom_ext_v_flash_a", exec_env = { - "//hw/top_earlgrey:fpga_cw310_rom_with_fake_keys": None, + "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( assemble = "{firmware}@{offset}", @@ -106,7 +111,8 @@ opentitan_test( opentitan_test( name = "rom_ext_v_flash_b", exec_env = { - "//hw/top_earlgrey:fpga_cw310_rom_with_fake_keys": None, + "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( assemble = "{firmware}@{offset}", @@ -122,7 +128,8 @@ opentitan_test( opentitan_test( name = "rom_ext_a_flash_a_bad_addr_trans", exec_env = { - "//hw/top_earlgrey:fpga_cw310_rom_with_fake_keys": None, + "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( assemble = "{firmware}@{offset}", diff --git a/sw/device/silicon_creator/rom/e2e/defs.bzl b/sw/device/silicon_creator/rom/e2e/defs.bzl index 0b88b2a1308ca..17389f03fa448 100644 --- a/sw/device/silicon_creator/rom/e2e/defs.bzl +++ b/sw/device/silicon_creator/rom/e2e/defs.bzl @@ -34,7 +34,8 @@ MSG_TEMPLATE_BFV_LCV = "{}{}\r\n{}{}\r\n(?s:.*){}{}\r\n{}{}\r\n".format( "{1}", ) -MSG_STARTING_ROM_EXT = "Starting ROM_EXT" +# When starting ROM_EXT, immutable section will always run first. +MSG_STARTING_ROM_EXT = "\nIMM_ROM_EXT v" MSG_PASS = "PASS!" diff --git a/sw/device/silicon_creator/rom_ext/BUILD b/sw/device/silicon_creator/rom_ext/BUILD index 02cc3804edd8b..d33991d2619fb 100644 --- a/sw/device/silicon_creator/rom_ext/BUILD +++ b/sw/device/silicon_creator/rom_ext/BUILD @@ -33,6 +33,18 @@ cc_library( ], ) +cc_library( + name = "rom_ext_manifest", + srcs = ["rom_ext_manifest.c"], + hdrs = ["rom_ext_manifest.h"], + target_compatible_with = [OPENTITAN_CPU], + deps = [ + "//hw/top_earlgrey/sw/autogen:top_earlgrey", + "//sw/device/lib/base:macros", + "//sw/device/silicon_creator/lib:manifest", + ], +) + dual_cc_library( name = "rom_ext_boot_policy_ptrs", srcs = dual_inputs( @@ -207,6 +219,7 @@ cc_library( ":rescue", ":rom_ext_boot_policy", ":rom_ext_boot_policy_ptrs", + ":rom_ext_manifest", ":sigverify_keys", "//hw/ip/sram_ctrl/data:sram_ctrl_c_regs", "//hw/top_earlgrey/ip_autogen/flash_ctrl:flash_ctrl_c_regs", @@ -220,9 +233,11 @@ cc_library( "//sw/device/silicon_creator/lib:boot_data", "//sw/device/silicon_creator/lib:boot_log", "//sw/device/silicon_creator/lib:dbg_print", + "//sw/device/silicon_creator/lib:epmp_state", "//sw/device/silicon_creator/lib:manifest", "//sw/device/silicon_creator/lib:manifest_def", "//sw/device/silicon_creator/lib:shutdown", + "//sw/device/silicon_creator/lib/base:boot_measurements", "//sw/device/silicon_creator/lib/base:chip", "//sw/device/silicon_creator/lib/base:sec_mmio", "//sw/device/silicon_creator/lib/base:static_critical", diff --git a/sw/device/silicon_creator/rom_ext/rom_ext.c b/sw/device/silicon_creator/rom_ext/rom_ext.c index 1be1588a56736..b50ba4ff08b88 100644 --- a/sw/device/silicon_creator/rom_ext/rom_ext.c +++ b/sw/device/silicon_creator/rom_ext/rom_ext.c @@ -46,6 +46,7 @@ #include "sw/device/silicon_creator/rom_ext/rescue.h" #include "sw/device/silicon_creator/rom_ext/rom_ext_boot_policy.h" #include "sw/device/silicon_creator/rom_ext/rom_ext_boot_policy_ptrs.h" +#include "sw/device/silicon_creator/rom_ext/rom_ext_manifest.h" #include "sw/device/silicon_creator/rom_ext/sigverify_keys.h" #include "flash_ctrl_regs.h" // Generated. @@ -140,17 +141,6 @@ static uint32_t rom_ext_current_slot(void) { return side; } -OT_WARN_UNUSED_RESULT -const manifest_t *rom_ext_manifest(void) { - uint32_t pc = 0; - asm("auipc %[pc], 0;" : [pc] "=r"(pc)); - const uint32_t kFlashHalf = TOP_EARLGREY_FLASH_CTRL_MEM_SIZE_BYTES / 2; - // Align the PC to the current flash side. The ROM_EXT must be the first - // entity in each flash side, so this alignment is the manifest address. - pc &= ~(kFlashHalf - 1); - return (const manifest_t *)pc; -} - void rom_ext_check_rom_expectations(void) { // Check the ePMP state. SHUTDOWN_IF_ERROR(epmp_state_check()); @@ -619,11 +609,8 @@ static rom_error_t rom_ext_start(boot_data_t *boot_data, boot_log_t *boot_log) { dbg_printf("Starting ROM_EXT %u.%u\r\n", self->version_major, self->version_minor); - // Establish our identity. + // Prepare dice chain builder for CDI_1. HARDENED_RETURN_IF_ERROR(dice_chain_init()); - HARDENED_RETURN_IF_ERROR(dice_chain_attestation_silicon()); - HARDENED_RETURN_IF_ERROR( - dice_chain_attestation_creator(&boot_measurements.rom_ext, self)); // Initialize the boot_log in retention RAM. const chip_info_t *rom_chip_info = (const chip_info_t *)_rom_chip_info_start; diff --git a/sw/device/silicon_creator/rom_ext/rom_ext_manifest.c b/sw/device/silicon_creator/rom_ext/rom_ext_manifest.c new file mode 100644 index 0000000000000..7210301235926 --- /dev/null +++ b/sw/device/silicon_creator/rom_ext/rom_ext_manifest.c @@ -0,0 +1,23 @@ +// 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/silicon_creator/rom_ext/rom_ext_manifest.h" + +#include "sw/device/silicon_creator/lib/manifest.h" + +#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" // Generated. + +enum { + kFlashHalf = TOP_EARLGREY_FLASH_CTRL_MEM_SIZE_BYTES / 2, +}; + +const manifest_t *rom_ext_manifest(void) { + uintptr_t pc = 0; + asm("auipc %[pc], 0;" : [pc] "=r"(pc)); + + // Align the PC to the current flash side. The ROM_EXT must be the first + // entity in each flash side, so this alignment is the manifest address. + pc &= ~((uintptr_t)kFlashHalf - 1); + return (const manifest_t *)pc; +} diff --git a/sw/device/silicon_creator/rom_ext/rom_ext_manifest.h b/sw/device/silicon_creator/rom_ext/rom_ext_manifest.h new file mode 100644 index 0000000000000..22d5b6324a0fb --- /dev/null +++ b/sw/device/silicon_creator/rom_ext/rom_ext_manifest.h @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_ROM_EXT_MANIFEST_H_ +#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_ROM_EXT_MANIFEST_H_ + +#include "sw/device/lib/base/macros.h" +#include "sw/device/silicon_creator/lib/manifest.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Return the pointer to rom_ext manifest on the active flash bank. + */ +OT_WARN_UNUSED_RESULT +const manifest_t *rom_ext_manifest(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_ROM_EXT_MANIFEST_H_