From cecb926302d8b2a60c52ac8775bfad491b69e88f Mon Sep 17 00:00:00 2001 From: Chris Frantz Date: Tue, 24 Sep 2024 13:14:21 -0700 Subject: [PATCH 1/3] [rom_ext,ownership] Allow DEV chips to erase the owner In order to facilitate debuging and manual test flows for ownerhsip transfer, we allow the owner pages to be erased if and only if the chip is in the DEV lifecycle state AND the ROM_EXT was specifically built to allow owner erase. Signed-off-by: Chris Frantz (cherry picked from commit a14571e0453b4855fe15c8dcb33a4b6095deedfe) (cherry picked from commit 129451bb81db3586376130b7f1a791ea1ebcf612) --- sw/device/silicon_creator/rom_ext/rescue.c | 27 ++++++++++++++++ sw/device/silicon_creator/rom_ext/rescue.h | 2 ++ sw/host/opentitanlib/src/rescue/serial.rs | 6 ++++ sw/host/opentitantool/src/command/rescue.rs | 34 +++++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/sw/device/silicon_creator/rom_ext/rescue.c b/sw/device/silicon_creator/rom_ext/rescue.c index 2931b8f69c51d..1f3a1508d3397 100644 --- a/sw/device/silicon_creator/rom_ext/rescue.c +++ b/sw/device/silicon_creator/rom_ext/rescue.c @@ -110,10 +110,37 @@ static void change_speed(void) { } } +#ifdef ROM_EXT_KLOBBER_ALLOWED +// In order to facilitate debuging and manual test flows for ownerhsip transfer, +// we allow the owner pages to be erased if and only if the chip is in the DEV +// lifecycle state AND the ROM_EXT was specifically built to allow owner erase. +// +// In the general case, the `KLBR` command does not exist. It can only be +// enabled by silicon_creator and only for DEV chips. +static void ownership_erase(void) { + lifecycle_state_t lc_state = lifecycle_state_get(); + if (lc_state == kLcStateDev) { + OT_DISCARD(flash_ctrl_info_erase(&kFlashCtrlInfoPageOwnerSlot0, + kFlashCtrlEraseTypePage)); + OT_DISCARD(flash_ctrl_info_erase(&kFlashCtrlInfoPageOwnerSlot1, + kFlashCtrlEraseTypePage)); + dbg_printf("ok: erased owner blocks\r\n"); + } else { + dbg_printf("error: erase not allowed in state %x\r\n", lc_state); + } +} +#endif + static void validate_mode(uint32_t mode, rescue_state_t *state, boot_data_t *bootdata) { dbg_printf("\r\nmode: %C\r\n", bitfield_byteswap32(mode)); hardened_bool_t allow = owner_rescue_command_allowed(state->config, mode); +#ifdef ROM_EXT_KLOBBER_ALLOWED + if (mode == kRescueModeKlobber) { + ownership_erase(); + return; + } +#endif if (allow == kHardenedBoolTrue) { switch (mode) { case kRescueModeBaud: diff --git a/sw/device/silicon_creator/rom_ext/rescue.h b/sw/device/silicon_creator/rom_ext/rescue.h index 1d94ebf2e865c..0aa5c4d758148 100644 --- a/sw/device/silicon_creator/rom_ext/rescue.h +++ b/sw/device/silicon_creator/rom_ext/rescue.h @@ -28,6 +28,8 @@ typedef enum { kRescueModeBootSvcRsp = 0x42525350, /** `BREQ` */ kRescueModeBootSvcReq = 0x42524551, + /** `KLBR` */ + kRescueModeKlobber = 0x4b4c4252, /** `OWNR` */ kRescueModeOwnerBlock = 0x4f574e52, /** `OPG0` */ diff --git a/sw/host/opentitanlib/src/rescue/serial.rs b/sw/host/opentitanlib/src/rescue/serial.rs index b126018a91911..82388645fef28 100644 --- a/sw/host/opentitanlib/src/rescue/serial.rs +++ b/sw/host/opentitanlib/src/rescue/serial.rs @@ -34,6 +34,7 @@ impl RescueSerial { pub const GET_OWNER_PAGE0: [u8; 4] = *b"OPG0"; pub const GET_OWNER_PAGE1: [u8; 4] = *b"OPG1"; pub const OT_ID: [u8; 4] = *b"OTID"; + pub const ERASE_OWNER: [u8; 4] = *b"KLBR"; pub const WAIT: [u8; 4] = *b"WAIT"; const BAUD_115K: [u8; 4] = *b"115K"; @@ -184,4 +185,9 @@ impl RescueSerial { xm.send(&*self.uart, data)?; Ok(()) } + + pub fn erase_owner(&self) -> Result<()> { + self.set_mode(Self::ERASE_OWNER)?; + Ok(()) + } } diff --git a/sw/host/opentitantool/src/command/rescue.rs b/sw/host/opentitantool/src/command/rescue.rs index 34266050dc806..6aec7b1b88b7d 100644 --- a/sw/host/opentitantool/src/command/rescue.rs +++ b/sw/host/opentitantool/src/command/rescue.rs @@ -455,6 +455,39 @@ impl CommandDispatch for GetOwnerConfig { } } +#[derive(Debug, Args)] +pub struct EraseOwner { + #[command(flatten)] + params: UartParams, + #[arg( + long, + default_value_t = true, + action = clap::ArgAction::Set, + help = "Reset the target to enter rescue mode" + )] + reset_target: bool, + #[arg(long, default_value_t = false, help = "Really erase the owner config")] + really: bool, +} + +impl CommandDispatch for EraseOwner { + fn run( + &self, + _context: &dyn Any, + transport: &TransportWrapper, + ) -> Result>> { + if self.really { + let uart = self.params.create(transport)?; + let rescue = RescueSerial::new(uart); + rescue.enter(transport, self.reset_target)?; + rescue.erase_owner()?; + Ok(None) + } else { + Err(anyhow!("The owner may only be erased on DEV lifecycle-state chips with a ROM_EXT configured to permit owner erasing.\n\nUse the `--really` flag to send the command.")) + } + } +} + #[derive(Debug, Subcommand, CommandDispatch)] pub enum BootSvcCommand { Get(GetBootSvc), @@ -467,6 +500,7 @@ pub enum BootSvcCommand { pub enum RescueCommand { #[command(subcommand)] BootSvc(BootSvcCommand), + EraseOwner(EraseOwner), GetBootLog(GetBootLog), GetDeviceId(GetDeviceId), Firmware(Firmware), From acceedd924495fcb29c8509cb87a237072ac9bd1 Mon Sep 17 00:00:00 2001 From: Chris Frantz Date: Wed, 11 Sep 2024 08:41:07 -0700 Subject: [PATCH 2/3] [rom_ext,ownership] Migrate FPGA and sival users to ECDSA 1. Generate owner and application keys for the `SiVal` user in the CloudKMS instance. Export the public components of those keys to the codebase (see `sw/device/silicon_creator/rom_ext/sival/keys/README.md`). 2. Add the keys to the appropriate exec_envs. 3. Add a config setting `//signing:owner_key_type` for selecting between RSA and ECDSA keys (RSA keys are for the currently released ROM_EXT 0.4). Signed-off-by: Chris Frantz (cherry picked from commit b3af7c1a2f7694bbd027d28f19073256d3169683) (cherry picked from commit 35ed76c1dd3690c9b09938d476b1fc7f2cf4629b) --- hw/top_earlgrey/BUILD | 1 - signing/BUILD | 50 +++++ .../lib/ownership/test_owner.c | 14 -- sw/device/silicon_creator/rom_ext/defs.bzl | 6 + sw/device/silicon_creator/rom_ext/sival/BUILD | 175 ++++++++---------- .../silicon_creator/rom_ext/sival/keys/BUILD | 16 ++ .../rom_ext/sival/keys/README.md | 41 ++++ .../rom_ext/sival/keys/appkey_dev_0.der | Bin 0 -> 91 bytes .../rom_ext/sival/keys/appkey_dev_0.h | 16 ++ .../rom_ext/sival/keys/appkey_prod_0.der | Bin 0 -> 91 bytes .../rom_ext/sival/keys/appkey_prod_0.h | 16 ++ .../rom_ext/sival/keys/appkey_test_0.der | Bin 0 -> 91 bytes .../rom_ext/sival/keys/appkey_test_0.h | 16 ++ .../sival/keys/ownership_activate_key.der | Bin 0 -> 91 bytes .../sival/keys/ownership_activate_key.h | 15 ++ .../sival/keys/ownership_owner_key.der | Bin 0 -> 91 bytes .../rom_ext/sival/keys/ownership_owner_key.h | 15 ++ .../sival/keys/ownership_unlock_key.der | Bin 0 -> 91 bytes .../rom_ext/sival/keys/ownership_unlock_key.h | 15 ++ .../rom_ext/sival/sival_owner.c | 150 +++++++++++++++ 20 files changed, 433 insertions(+), 113 deletions(-) create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/README.md create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/appkey_dev_0.der create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/appkey_dev_0.h create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/appkey_prod_0.der create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/appkey_prod_0.h create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/appkey_test_0.der create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/appkey_test_0.h create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/ownership_activate_key.der create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/ownership_activate_key.h create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/ownership_owner_key.der create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/ownership_owner_key.h create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/ownership_unlock_key.der create mode 100644 sw/device/silicon_creator/rom_ext/sival/keys/ownership_unlock_key.h create mode 100644 sw/device/silicon_creator/rom_ext/sival/sival_owner.c diff --git a/hw/top_earlgrey/BUILD b/hw/top_earlgrey/BUILD index e4a69e89efbda..a11bab4feb0e5 100644 --- a/hw/top_earlgrey/BUILD +++ b/hw/top_earlgrey/BUILD @@ -8,7 +8,6 @@ load( ) load( "//rules/opentitan:defs.bzl", - "CLEAR_KEY_SET", "DEFAULT_TEST_FAILURE_MSG", "DEFAULT_TEST_SUCCESS_MSG", "fpga_cw305", diff --git a/signing/BUILD b/signing/BUILD index e68909fe7b8f4..e9561b1c0f592 100644 --- a/signing/BUILD +++ b/signing/BUILD @@ -2,6 +2,8 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 +load("@bazel_skylib//rules:common_settings.bzl", "string_flag") + package(default_visibility = ["//visibility:public"]) label_flag( @@ -16,6 +18,54 @@ config_setting( }, ) +# TODO(#24641): Simplify key selection after eliminating RSA keys. +# The currently released ROM_EXT binary for ES silicon (version 0.4) supports +# only RSA keys. The next release will eliminate RSA keys in favor of ECDSA +# keys. In order to allow current users to continue to build RSA-signed +# applications (e.g. tests), we default to an `owner_key_type` of RSA. Ad-hoc +# testing on ES DEV parts running the as-yet unreleased ROM_EXT (at the head +# of this branch) can select ECDSA keys. +# +# Note that the FPGA targets always run the ROM_EXT from head, and always +# select an ECDSA key regardless of the `owner_key_type` setting. +# +# This key-type selection will be removed when we finish converting to ECDSA +# and eliminate RSA keys for application signing. +string_flag( + name = "owner_key_type", + build_setting_default = "rsa", + values = [ + "rsa", + "ecdsa", + ], +) + +config_setting( + name = "owner_key_rsa", + flag_values = {":owner_key_type": "rsa"}, +) + +config_setting( + name = "owner_key_ecdsa", + flag_values = {":owner_key_type": "ecdsa"}, +) + +config_setting( + name = "test_keys_rsa", + flag_values = { + ":token": "//signing/tokens:local", + ":owner_key_type": "rsa", + }, +) + +config_setting( + name = "test_keys_ecdsa", + flag_values = { + ":token": "//signing/tokens:local", + ":owner_key_type": "ecdsa", + }, +) + filegroup( name = "none_key", srcs = ["skip.bit"], diff --git a/sw/device/silicon_creator/lib/ownership/test_owner.c b/sw/device/silicon_creator/lib/ownership/test_owner.c index ff0399bc0eb55..da764a4fdfb4b 100644 --- a/sw/device/silicon_creator/lib/ownership/test_owner.c +++ b/sw/device/silicon_creator/lib/ownership/test_owner.c @@ -132,13 +132,6 @@ rom_error_t sku_creator_owner_init(boot_data_t *bootdata, ownership_seal_page(/*page=*/0); memcpy(&owner_page[1], &owner_page[0], sizeof(owner_page[0])); - RETURN_IF_ERROR(owner_block_parse(&owner_page[0], config, keyring)); - RETURN_IF_ERROR(owner_block_flash_apply(config->flash, kBootSlotA, - bootdata->primary_bl0_slot)); - RETURN_IF_ERROR(owner_block_flash_apply(config->flash, kBootSlotB, - bootdata->primary_bl0_slot)); - RETURN_IF_ERROR(owner_block_info_apply(config->info)); - // Since this module should only get linked in to FPGA builds, we can simply // thunk the ownership state to LockedOwner. bootdata->ownership_state = kOwnershipStateLockedOwner; @@ -151,13 +144,6 @@ rom_error_t sku_creator_owner_init(boot_data_t *bootdata, &owner_page[0])); owner_page_valid[0] = kOwnerPageStatusSealed; - OT_DISCARD(flash_ctrl_info_erase(&kFlashCtrlInfoPageOwnerSlot1, - kFlashCtrlEraseTypePage)); - OT_DISCARD(flash_ctrl_info_write(&kFlashCtrlInfoPageOwnerSlot1, 0, - sizeof(owner_page[0]) / sizeof(uint32_t), - &owner_page[0])); - owner_page_valid[1] = kOwnerPageStatusSealed; - OT_DISCARD(boot_data_write(bootdata)); dbg_printf("sku_creator_owner_init: saved to flash\r\n"); return kErrorOk; diff --git a/sw/device/silicon_creator/rom_ext/defs.bzl b/sw/device/silicon_creator/rom_ext/defs.bzl index 464c57ea73bca..51ec98c05b58d 100644 --- a/sw/device/silicon_creator/rom_ext/defs.bzl +++ b/sw/device/silicon_creator/rom_ext/defs.bzl @@ -10,3 +10,9 @@ ROM_EXT_VERSION = struct( MINOR = "1", SECURITY = "0", ) + +SLOTS = [ + "a", + "b", + "virtual", +] diff --git a/sw/device/silicon_creator/rom_ext/sival/BUILD b/sw/device/silicon_creator/rom_ext/sival/BUILD index 0f954c41053dc..00d831a5b3040 100644 --- a/sw/device/silicon_creator/rom_ext/sival/BUILD +++ b/sw/device/silicon_creator/rom_ext/sival/BUILD @@ -15,6 +15,7 @@ load( "//sw/device/silicon_creator/imm_rom_ext:defs.bzl", "SLOT_A_IMM_ROM_EXT_SECTIONS", "SLOT_B_IMM_ROM_EXT_SECTIONS", + "SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS", ) package(default_visibility = ["//visibility:public"]) @@ -26,6 +27,12 @@ LINK_ORDER = [ "$(location //sw/device/lib/crt)", ] +SLOTS = { + "a": SLOT_A_IMM_ROM_EXT_SECTIONS, + "b": SLOT_B_IMM_ROM_EXT_SECTIONS, + "virtual": SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS, +} + manifest(d = { "name": "manifest_sival", "identifier": hex(CONST.ROM_EXT), @@ -40,110 +47,68 @@ manifest(d = { # You can manually create such a bitstream with: # # bazel build //hw/bitstream/universal:splice --//hw/bitstream/universal:env=//hw/top_earlgrey:fpga_cw310_sival -opentitan_binary( - name = "rom_ext_fake_prod_signed_slot_a", - ecdsa_key = {"//sw/device/silicon_creator/rom/keys/fake/ecdsa:prod_key_0_ecdsa_p256": "prod_key_0"}, - exec_env = [ - "//hw/top_earlgrey:silicon_creator", - "//hw/top_earlgrey:fpga_cw310", - "//hw/top_earlgrey:fpga_cw340", - "//hw/top_earlgrey:sim_dv_base", - "//hw/top_earlgrey:sim_verilator_base", - ], - extra_bazel_features = [ - "minsize", - "use_lld", - ], - immutable_rom_ext_sections = SLOT_A_IMM_ROM_EXT_SECTIONS["main"], - linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_a", - linkopts = LINK_ORDER, - manifest = ":manifest_sival", - # TODO(#26060): Temporarily disable SPX signing of ROM_EXT. - #spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, - deps = [ - "//sw/device/lib/crt", - "//sw/device/silicon_creator/lib:manifest_def", - "//sw/device/silicon_creator/rom_ext", - "//sw/device/silicon_creator/rom_ext/sival/keys", - ], -) - -opentitan_binary( - name = "rom_ext_fake_prod_signed_slot_b", - ecdsa_key = {"//sw/device/silicon_creator/rom/keys/fake/ecdsa:prod_key_0_ecdsa_p256": "prod_key_0"}, - exec_env = [ - "//hw/top_earlgrey:silicon_creator", - "//hw/top_earlgrey:fpga_cw310", - "//hw/top_earlgrey:fpga_cw340", - "//hw/top_earlgrey:sim_dv_base", - "//hw/top_earlgrey:sim_verilator_base", - ], - extra_bazel_features = [ - "minsize", - "use_lld", - ], - immutable_rom_ext_sections = SLOT_B_IMM_ROM_EXT_SECTIONS["main"], - linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_b", - linkopts = LINK_ORDER, - manifest = ":manifest_sival", - # TODO(#26060): Temporarily disable SPX signing of ROM_EXT. - #spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, - deps = [ - "//sw/device/lib/crt", - "//sw/device/silicon_creator/lib:manifest_def", - "//sw/device/silicon_creator/rom_ext", - "//sw/device/silicon_creator/rom_ext/sival/keys", - ], -) - -opentitan_binary( - name = "rom_ext_real_prod_signed_slot_a", - exec_env = [ - "//hw/top_earlgrey:silicon_creator", - "//hw/top_earlgrey:fpga_cw310", - ], - extra_bazel_features = [ - "minsize", - "use_lld", - ], - immutable_rom_ext_sections = SLOT_A_IMM_ROM_EXT_SECTIONS["main"], - linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_a", - linkopts = LINK_ORDER, - deps = [ - "//sw/device/lib/crt", - "//sw/device/silicon_creator/lib:manifest_def", - "//sw/device/silicon_creator/rom_ext", - "//sw/device/silicon_creator/rom_ext/sival/keys", - ], -) +[ + opentitan_binary( + name = "rom_ext_fake_prod_signed_slot_{}".format(slot), + ecdsa_key = {"//sw/device/silicon_creator/rom/keys/fake/ecdsa:prod_key_0_ecdsa_p256": "prod_key_0"}, + exec_env = [ + "//hw/top_earlgrey:silicon_creator", + "//hw/top_earlgrey:fpga_cw310", + "//hw/top_earlgrey:fpga_cw340", + "//hw/top_earlgrey:sim_dv_base", + "//hw/top_earlgrey:sim_verilator_base", + ], + extra_bazel_features = [ + "minsize", + "use_lld", + ], + immutable_rom_ext_sections = imm_sections["main"], + linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_{}".format(slot), + linkopts = LINK_ORDER, + manifest = ":manifest_sival", + # TODO(#26060): Temporarily disable SPX signing of ROM_EXT. + #spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, + deps = [ + ":sival_owner", + "//sw/device/lib/crt", + "//sw/device/silicon_creator/lib:manifest_def", + "//sw/device/silicon_creator/rom_ext", + ], + ) + for slot, imm_sections in SLOTS.items() +] -opentitan_binary( - name = "rom_ext_real_prod_signed_slot_b", - exec_env = [ - "//hw/top_earlgrey:silicon_creator", - "//hw/top_earlgrey:fpga_cw310", - ], - extra_bazel_features = [ - "minsize", - "use_lld", - ], - immutable_rom_ext_sections = SLOT_B_IMM_ROM_EXT_SECTIONS["main"], - linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_b", - linkopts = LINK_ORDER, - deps = [ - "//sw/device/lib/crt", - "//sw/device/silicon_creator/lib:manifest_def", - "//sw/device/silicon_creator/rom_ext", - "//sw/device/silicon_creator/rom_ext/sival/keys", - ], -) +[ + opentitan_binary( + name = "rom_ext_real_prod_signed_slot_{}".format(slot), + exec_env = [ + "//hw/top_earlgrey:silicon_creator", + "//hw/top_earlgrey:fpga_cw310", + "//hw/top_earlgrey:fpga_cw340", + ], + extra_bazel_features = [ + "minsize", + "use_lld", + ], + immutable_rom_ext_sections = imm_sections["main"], + linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_{}".format(slot), + linkopts = LINK_ORDER, + deps = [ + ":sival_owner", + "//sw/device/lib/crt", + "//sw/device/silicon_creator/lib:manifest_def", + "//sw/device/silicon_creator/rom_ext", + ], + ) + for slot, imm_sections in SLOTS.items() +] offline_presigning_artifacts( name = "presigning", testonly = True, srcs = [ - ":rom_ext_real_prod_signed_slot_a", - ":rom_ext_real_prod_signed_slot_b", + ":rom_ext_real_prod_signed_slot_{}".format(slot) + for slot in SLOTS ], ecdsa_key = { "//sw/device/silicon_creator/rom/keys/fake/ecdsa:prod_key_0_ecdsa_p256": "prod_key_0_ecdsa_p256", @@ -171,3 +136,17 @@ offline_signature_attach( ], tags = ["manual"], ) + +cc_library( + name = "sival_owner", + srcs = ["sival_owner.c"], + deps = [ + "//sw/device/silicon_creator/lib:boot_data", + "//sw/device/silicon_creator/lib/drivers:flash_ctrl", + "//sw/device/silicon_creator/lib/ownership", + "//sw/device/silicon_creator/lib/ownership:datatypes", + "//sw/device/silicon_creator/lib/ownership:owner_block", + "//sw/device/silicon_creator/rom_ext/sival/keys:includes", + ], + alwayslink = True, +) diff --git a/sw/device/silicon_creator/rom_ext/sival/keys/BUILD b/sw/device/silicon_creator/rom_ext/sival/keys/BUILD index 1256d8eac5a8d..5d6ab21332a75 100644 --- a/sw/device/silicon_creator/rom_ext/sival/keys/BUILD +++ b/sw/device/silicon_creator/rom_ext/sival/keys/BUILD @@ -6,6 +6,19 @@ load("//rules:signing.bzl", "keyset") package(default_visibility = ["//visibility:public"]) +cc_library( + name = "includes", + hdrs = [ + "appkey_dev_0.h", + "appkey_prod_0.h", + "appkey_test_0.h", + "earlgrey_z0_sival_1.h", + "ownership_activate_key.h", + "ownership_owner_key.h", + "ownership_unlock_key.h", + ], +) + cc_library( name = "keys", srcs = [ @@ -49,6 +62,9 @@ keyset( build_setting_default = "", keys = { "earlgrey_z0_sival_1.der": "earlgrey_z0_sival_1", + "appkey_dev_0.der": "appkey_dev_0", + "appkey_prod_0.der": "appkey_prod_0", + "appkey_test_0.der": "appkey_test_0", }, profile = "earlgrey_z0_sival", tool = "//signing:token", diff --git a/sw/device/silicon_creator/rom_ext/sival/keys/README.md b/sw/device/silicon_creator/rom_ext/sival/keys/README.md new file mode 100644 index 0000000000000..6bcaa37bbd0f7 --- /dev/null +++ b/sw/device/silicon_creator/rom_ext/sival/keys/README.md @@ -0,0 +1,41 @@ +# SiVAL owner and application keys + +The keys in this directory are the owner and application keys for the SiVAL owner. +The private components of these keys are stored in CloudKMS in the `ot-earlgrey-z0-sival` keyring. + +These keys were generated using the `gcloud` command line tool: + +```bash +KEYS=( + appkey_dev_0 + appkey_prod_0 + appkey_test_0 + ownership_owner_key + ownership_activate_key + ownership_unlock_key +) + +for KEY in ${KEYS[@]}; do + gcloud kms keys create ${KEY} \ + --keyring ot-earlgrey-z0-sival \ + --location us-west1 \ + --purpose "asymmetric-signing" \ + --default-algorithm "ec-sign-p256-sha256" \ + --protection-level hsm +done +``` + +The keys were then exported from CloudKMS using `hsmtool` and converted to C headers with `opentitantool`: + +```bash +for KEY in ${KEYS[@]}; do + hsmtool --token ot-earlgrey-z0-sival \ + ecdsa export \ + -l ${KEY} \ + -f der \ + sw/device/silicon_creator/rom_ext/sival/keys/${KEY}.der + + opentitantool ecdsa key export \ + sw/device/silicon_creator/rom_ext/sival/keys/${KEY}.der +done +``` diff --git a/sw/device/silicon_creator/rom_ext/sival/keys/appkey_dev_0.der b/sw/device/silicon_creator/rom_ext/sival/keys/appkey_dev_0.der new file mode 100644 index 0000000000000000000000000000000000000000..984231b2397db97bd75e66477d66896c77d81129 GIT binary patch literal 91 zcmXqrG!SNE*J|@PXUoLM#sOw9GqN)~F|f@2wLLp?rrl$<-j1hD@jL|+L~p*Gxi#q6 u7Wuc~?$X{m`Tvak9JqX!U6WzFFfV9(Nq>^)cgugRuP^@n`E*Xz><9q7xF(#EJ^5eZ*rLN)x(s*J#)tKs%MvH3cs)~ uVUKG}@tg8_fy0)s(g#~)`X9f(eMMx&);xSv4-_GgH+xUFHv?9G)wx99W{whgBQ tKPgld>7P1gvTbvW#?#DM;W;O>Ol{Zh)_Q-do8qyDPu%16D+ up2E0W_42a>pN0w2Z}xJ81pWH7K=#mH|3g;If^8FjEKzP+t!XDSBOU;?^(2u1 literal 0 HcmV?d00001 diff --git a/sw/device/silicon_creator/rom_ext/sival/keys/ownership_owner_key.h b/sw/device/silicon_creator/rom_ext/sival/keys/ownership_owner_key.h new file mode 100644 index 0000000000000..8a79fae26cfa8 --- /dev/null +++ b/sw/device/silicon_creator/rom_ext/sival/keys/ownership_owner_key.h @@ -0,0 +1,15 @@ +// 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_SIVAL_KEYS_OWNERSHIP_OWNER_KEY_H_ +#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_SIVAL_KEYS_OWNERSHIP_OWNER_KEY_H_ + +#define OWNERSHIP_OWNER_KEY \ + { \ + 0x25d3e660, 0x6b9401bb, 0x2d1f5aee, 0x875afd25, 0xaaec4927, 0xda4db14f, \ + 0x5d8589d7, 0xa1d16920, 0x3e1c985f, 0x2382ab29, 0x8691f8a4, \ + 0xc23a8311, 0x1dc2bd4f, 0x52faf2a0, 0xecbd0854, 0x4c80901b, \ + } + +#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_SIVAL_KEYS_OWNERSHIP_OWNER_KEY_H_ diff --git a/sw/device/silicon_creator/rom_ext/sival/keys/ownership_unlock_key.der b/sw/device/silicon_creator/rom_ext/sival/keys/ownership_unlock_key.der new file mode 100644 index 0000000000000000000000000000000000000000..1878ca686c990ff711dfdf09e83ded5132140151 GIT binary patch literal 91 zcmXqrG!SNE*J|@PXUoLM#sOw9GqN)~F|gR4td88gvPjZ3YIpMFnGFSQd(FR#2xdI! uzw*#v_X0UP8}^Q0a}-}iT-S_e;Lbe~d_?5Uyyiz!Ry1;1uQFfhwF>}zMI*5Q literal 0 HcmV?d00001 diff --git a/sw/device/silicon_creator/rom_ext/sival/keys/ownership_unlock_key.h b/sw/device/silicon_creator/rom_ext/sival/keys/ownership_unlock_key.h new file mode 100644 index 0000000000000..f442418ace36d --- /dev/null +++ b/sw/device/silicon_creator/rom_ext/sival/keys/ownership_unlock_key.h @@ -0,0 +1,15 @@ +// 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_SIVAL_KEYS_OWNERSHIP_UNLOCK_KEY_H_ +#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_SIVAL_KEYS_OWNERSHIP_UNLOCK_KEY_H_ + +#define OWNERSHIP_UNLOCK_KEY \ + { \ + 0xbba01e3e, 0x8fd4e130, 0x141168e0, 0x46bd37f7, 0x93998070, 0x455abb63, \ + 0xb3a97219, 0x3dc97b59, 0x37a94aba, 0x810a3baa, 0x83e294a8, \ + 0xc414ec9e, 0x0b6dc453, 0xd7295f00, 0x9c21ea58, 0x3c0788fa, \ + } + +#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_SIVAL_KEYS_OWNERSHIP_UNLOCK_KEY_H_ diff --git a/sw/device/silicon_creator/rom_ext/sival/sival_owner.c b/sw/device/silicon_creator/rom_ext/sival/sival_owner.c new file mode 100644 index 0000000000000..c292144e77cf0 --- /dev/null +++ b/sw/device/silicon_creator/rom_ext/sival/sival_owner.c @@ -0,0 +1,150 @@ +// 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/base/hardened_memory.h" +#include "sw/device/lib/base/macros.h" +#include "sw/device/lib/base/memory.h" +#include "sw/device/silicon_creator/lib/dbg_print.h" +#include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h" +#include "sw/device/silicon_creator/lib/error.h" +#include "sw/device/silicon_creator/lib/ownership/owner_block.h" +#include "sw/device/silicon_creator/lib/ownership/ownership.h" +#include "sw/device/silicon_creator/lib/ownership/ownership_key.h" +#include "sw/device/silicon_creator/rom_ext/sival/keys/appkey_dev_0.h" +#include "sw/device/silicon_creator/rom_ext/sival/keys/appkey_prod_0.h" +#include "sw/device/silicon_creator/rom_ext/sival/keys/appkey_test_0.h" +#include "sw/device/silicon_creator/rom_ext/sival/keys/ownership_activate_key.h" +#include "sw/device/silicon_creator/rom_ext/sival/keys/ownership_owner_key.h" +#include "sw/device/silicon_creator/rom_ext/sival/keys/ownership_unlock_key.h" + +/* + * This module overrides the weak `sku_creator_owner_init` symbol in + * ownership.c, thus allowing existing sival chips without an ownership + * configuration to receive their ownership config simply installing the latest + * ROM_EXT. + */ + +#define SIVAL_OWNER_CONFIG_VERSION 1 + +rom_error_t sku_creator_owner_init(boot_data_t *bootdata, + owner_config_t *config, + owner_application_keyring_t *keyring) { + owner_key_t owner = (owner_key_t){ + // Although this is an ECDSA key, we initialize the `raw` member of the + // union to zero-initialize the unused space. + .raw = OWNERSHIP_OWNER_KEY}; + ownership_state_t state = bootdata->ownership_state; + + if (state == kOwnershipStateUnlockedSelf || + state == kOwnershipStateUnlockedAny || + state == kOwnershipStateUnlockedEndorsed) { + // Nothing to do when in an unlocked state. + return kErrorOk; + } else if (state == kOwnershipStateLockedOwner) { + if (hardened_memeq(owner.raw, owner_page[0].owner_key.raw, + ARRAYSIZE(owner.raw)) != kHardenedBoolTrue || + SIVAL_OWNER_CONFIG_VERSION <= owner_page[0].config_version) { + // Different owner or already newest config version; nothing to do. + return kErrorOk; + } + } else { + // State is an unknown value, which is the same as kOwnershipStateRecovery. + // We'll not return, thus allowing the owner config below to be programmed + // into flash. + } + + memset(&owner_page[0], 0, sizeof(owner_page[0])); + owner_page[0].header.tag = kTlvTagOwner; + owner_page[0].header.length = 2048; + owner_page[0].struct_version = 0; + owner_page[0].sram_exec_mode = kOwnerSramExecModeDisabledLocked; + owner_page[0].ownership_key_alg = kOwnershipKeyAlgEcdsaP256; + owner_page[0].config_version = SIVAL_OWNER_CONFIG_VERSION; + owner_page[0].min_security_version_bl0 = UINT32_MAX; + owner_page[0].owner_key = owner; + owner_page[0].activate_key = (owner_key_t){ + // Although this is an ECDSA key, we initialize the `raw` member of the + // union to zero-initialize the unused space. + .raw = OWNERSHIP_ACTIVATE_KEY}; + owner_page[0].unlock_key = (owner_key_t){ + // Although this is an ECDSA key, we initialize the `raw` member of the + // union to zero-initialize the unused space. + .raw = OWNERSHIP_UNLOCK_KEY}; + + owner_application_key_t *app = (owner_application_key_t *)owner_page[0].data; + *app = (owner_application_key_t){ + .header = + { + .tag = kTlvTagApplicationKey, + .length = kTlvLenApplicationKeyEcdsa, + }, + .key_alg = kOwnershipKeyAlgEcdsaP256, + .key_domain = kOwnerAppDomainTest, + .key_diversifier = {0}, + .usage_constraint = 0, + .data = + { + .ecdsa = APPKEY_TEST_0, + }, + }; + + app = (owner_application_key_t *)((uintptr_t)app + app->header.length); + *app = (owner_application_key_t){ + .header = + { + .tag = kTlvTagApplicationKey, + .length = kTlvLenApplicationKeyEcdsa, + }, + .key_alg = kOwnershipKeyAlgEcdsaP256, + .key_domain = kOwnerAppDomainProd, + .key_diversifier = {0}, + .usage_constraint = 0, + .data = + { + .ecdsa = APPKEY_PROD_0, + }, + }; + + app = (owner_application_key_t *)((uintptr_t)app + app->header.length); + *app = (owner_application_key_t){ + .header = + { + .tag = kTlvTagApplicationKey, + .length = kTlvLenApplicationKeyEcdsa, + }, + .key_alg = kOwnershipKeyAlgEcdsaP256, + .key_domain = kOwnerAppDomainDev, + .key_diversifier = {0}, + .usage_constraint = 0, + .data = + { + .ecdsa = APPKEY_DEV_0, + }, + }; + + // Fill the remainder of the data segment with the end tag (0x5a5a5a5a). + app = (owner_application_key_t *)((uintptr_t)app + app->header.length); + size_t len = (uintptr_t)(owner_page[0].data + sizeof(owner_page[0].data)) - + (uintptr_t)app; + memset(app, 0x5a, len); + + ownership_seal_page(/*page=*/0); + memcpy(&owner_page[1], &owner_page[0], sizeof(owner_page[0])); + + // Since this code should only execute when the ownership state is unknown, we + // can thunk the ownership state to LockedOwner. + bootdata->ownership_state = kOwnershipStateLockedOwner; + + // Write the configuration to page 0. + OT_DISCARD(flash_ctrl_info_erase(&kFlashCtrlInfoPageOwnerSlot0, + kFlashCtrlEraseTypePage)); + OT_DISCARD(flash_ctrl_info_write(&kFlashCtrlInfoPageOwnerSlot0, 0, + sizeof(owner_page[0]) / sizeof(uint32_t), + &owner_page[0])); + owner_page_valid[0] = kOwnerPageStatusSealed; + + OT_DISCARD(boot_data_write(bootdata)); + dbg_printf("sku_creator_owner_init: saved to flash\r\n"); + return kErrorOk; +} From fc0db39844ad52229a68d6d1af5faab4e54734c3 Mon Sep 17 00:00:00 2001 From: Chris Frantz Date: Tue, 24 Sep 2024 20:13:19 -0700 Subject: [PATCH 3/3] [ownership] Create `dummy` ECDSA keys 1. Create `dummy` ECDSA application keys for ownership transfer tests. 2. Delete `dummy` RSA application keys. Signed-off-by: Chris Frantz (cherry picked from commit 2a8092f80cc2099505351b5b6352161fe919239b) (cherry picked from commit 440db25b02cc5d25778970a5c6b033ce5b75722d) --- .../keys/dummy/app_prod_rsa_3072_exp_f4.der | Bin 1793 -> 0 bytes .../keys/dummy/app_prod_rsa_3072_exp_f4.pub.der | Bin 398 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 sw/device/silicon_creator/lib/ownership/keys/dummy/app_prod_rsa_3072_exp_f4.der delete mode 100644 sw/device/silicon_creator/lib/ownership/keys/dummy/app_prod_rsa_3072_exp_f4.pub.der diff --git a/sw/device/silicon_creator/lib/ownership/keys/dummy/app_prod_rsa_3072_exp_f4.der b/sw/device/silicon_creator/lib/ownership/keys/dummy/app_prod_rsa_3072_exp_f4.der deleted file mode 100644 index a41d54d309f0ffb238dbdd2ec47578cf94f419c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1793 zcmV+c2mbglf(HEp0RS)!1_>&LNQUt=P-f>;{pKy0)hd70MSXoTiD$E zrB?!jrV7$K;JC*BDwCu3u9rrXGWh4y%Yn-3K>@z2ZfR0G&r40l`^&E2sq(ngQvki8 zyEdJ37?_3E#iHhA^6h!Kul@8pvXClv0HxOYLlq7xZ z#HC3MUhH+IxgUb8LpEXRhxFCn*(R4MJiVwDBtJQIcVcv?yIx9Y{*j!j@)gJYClj`nj2aAYcBi$9QEQuD0Ls zSC(~|?x9-lC5JPvMYQ6#9ejvcjzsZ^ibqDSRD}dKkF?VtFxj+InqS<(#_0~F9<5-F zR!Jk1Zt43^mC=CBQvw44009Dm0e}M%bQUKL$6lTCS%6%0O^~$ZrsX#omkVVH5--(T zfzDv>Ta@gxq0EyTGwF>FZ8lK-7Aq)r@)qsU+Q;U*RPQZ)`F7hkN|Vq`lOHrW8;?11 zh8*ZpNr;AgReB`Wr!*S!UQA+Q$LQ|>Gv$%CbOFwSpET7R8}Jh0$FY@nXJtKmH5ua} zK`?$UF^^Uq2;0RUJhqdb?&n}L5Vuj8=)G0*%Rle6EYA_;fHwniWtr~yZ2INvCB$yP z!LJtdk)NcgN%*Iss8#6YFEToDLeAXD3YC5&hVf4P(k+e|RN!qRG510fmEAUH;bqq= z15O&I!g+xR;OnZX9?>&)oqJ+1b5}ive7xA_)=7V8E)jP2JcN)^)y~C{rHI9Pa!;bx z@bwV{kJfobR1y%H#)3pLph@>;=;ot-f6oP?Z#SZR@8ZI`{_mn1uLC?Na}%%bi>F8! zui_rs;?Q-QT`Gv~gHhOycP~*hC8bU4>z(Ou9Sdk)1o_YVa1!jORAB;v!2s3+GMs#X zdXOTObJyhoo?spe-oOO=b})k4qB4m3r^yh2ft6hPjj$9z#oaGSNG}A7+v5)a2LVx( z-6_m*Y+T0YtX9+Wk8CUVHsv(j?`1P2DlTcT6HboU+W&ufc%Y)OB9=iXd>#dDo~|Ij zP}(r3x5?t4%56JE$#hz{8~41I8evolPGTdmuWJVJ!tL?o;wwA3p4QYViEz0shg~Bu zHK~lsC&KAJOw^HYlpx@!V~!2tSMMqI{j{QGDEvFa~`UCV@; zHfNwwjr|jb9-QtzVI_Vs@-GMaLc22B-BbRq$z?`^R)jo#>1<|-@KKWdeY4=6gj=jH zkzZ@WhE7Xx`L9rTds?A^1%W9--!3IJ)!8%_vqE5|k@@wVZG&nXw?z^KSZTXxV>IBt zs8M9l*{z~onYJE_LF}Ly*`C5b?K=BtfAYtF#>_X0NWb#SQA_15$v!ZB85NZ4^J52@WlaJvDrG3rshhj(wzyGACmP3-bIL2$!&BM5E3Fav*q%_TWnjdmFr`FuOG zZ@1eb+YG=%#d2OTY&HMzH@e)nssmKeo#II(IIn5dwk04+%xc z(nq4<@cmD@UUUs6xP?9KmUu3FUhJruVDs7iq<4Cj!scez1J*h`j51nPpAW%mc@O3+rZAb7osgc}iS53gZz9XrD)Ileo`(MXA!@K#PMd55L# z(L+(B`~sc@X+Qz3%zfEE^Np#LBz^3}rAZB5>~*HOAA+nyHeu?A^wr+u?l_1wWPjsQ z$*{Y8oqs5)Br1rQcybrv1O+bG0bz%j1BAHkSPr*u?e=9KJ<*#YZHMJ6Zt}sT zUcmg&ng24dt9=o32S>|(3UO~^E{FDkAL7d{Rl?K_LSh)S@ha?5l3|OqC|y<^NJ`Se zmS$=^UDpx%xtV|HANW(SXfU0s{d60p;k;>Hq)$