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

Cherry-pick to master [rom_ext_e2e] Add an ownership transfer test #25668

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 5 additions & 3 deletions quality/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -173,19 +173,21 @@ RUST_TARGETS = [
"//sw/host/hsmtool:hsmlib",
"//sw/host/hsmtool:hsmlib_test",
"//sw/host/hsmtool/acorn:acorn",
"//sw/host/ot_certs:ot_certs",
"//sw/host/ot_certs:ot_certs_test",
"//sw/host/opentitanlib:opentitanlib",
"//sw/host/opentitanlib:opentitanlib_test",
"//sw/host/opentitansession:opentitansession",
"//sw/host/opentitantool:opentitantool",
"//sw/host/ot_certs:ot_certs",
"//sw/host/ot_certs:ot_certs_test",
"//sw/host/tests/chip/gpio:gpio",
"//sw/host/tests/chip/power_virus:power_virus",
"//sw/host/tests/chip/spi_device:spi_passthru",
"//sw/host/tests/ownership:transfer_lib",
"//sw/host/tests/ownership:transfer_test",
"//sw/host/tests/rom/e2e_bootstrap_disabled:e2e_bootstrap_disabled",
"//sw/host/tests/rom/e2e_bootstrap_entry:e2e_bootstrap_entry",
"//sw/host/tests/rom/e2e_chip_specific_startup:e2e_chip_specific_startup",
"//sw/host/tests/rom/sw_strap_value:sw_strap_value",
"//sw/host/tests/chip/spi_device:spi_passthru",
"//sw/host/tests/xmodem:lrzsz_test",
"//sw/host/tests/xmodem:xmodem",
"//sw/host/sphincsplus:sphincsplus",
Expand Down
30 changes: 30 additions & 0 deletions sw/device/silicon_creator/lib/ownership/keys/dummy/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 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 = "owner_key",
srcs = ["owner_ecdsa_p256.der"],
)

filegroup(
name = "activate_key",
srcs = ["activate_ecdsa_p256.der"],
)

filegroup(
name = "unlock_key",
srcs = ["unlock_ecdsa_p256.der"],
)

filegroup(
name = "app_prod",
srcs = ["app_prod_rsa_3072_exp_f4.der"],
)

filegroup(
name = "app_prod_pub",
srcs = ["app_prod_rsa_3072_exp_f4.pub.der"],
)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
51 changes: 51 additions & 0 deletions sw/device/silicon_creator/rom_ext/e2e/ownership/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# 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 = "ownership_transfer_test",
srcs = ["//sw/device/silicon_creator/rom_ext/e2e/verified_boot:boot_test"],
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
},
fpga = fpga_params(
# This test doesn't change OTP, but it modifies the ownership INFO
# pages, so we need to clear the bitstream after the test, which is
# what the `changes_otp` parameter actually does.
changes_otp = True,
data = [
"//sw/device/silicon_creator/lib/ownership/keys/dummy:activate_key",
"//sw/device/silicon_creator/lib/ownership/keys/dummy:app_prod_pub",
"//sw/device/silicon_creator/lib/ownership/keys/dummy:owner_key",
"//sw/device/silicon_creator/lib/ownership/keys/dummy:unlock_key",
"//sw/device/silicon_creator/lib/ownership/keys/fake:unlock_key",
],
test_cmd = """
--clear-bitstream
--bootstrap={firmware}
--unlock-key=$(location //sw/device/silicon_creator/lib/ownership/keys/fake:unlock_key)
--next-owner-key=$(location //sw/device/silicon_creator/lib/ownership/keys/dummy:owner_key)
--next-unlock-key=$(location //sw/device/silicon_creator/lib/ownership/keys/dummy:unlock_key)
--next-activate-key=$(location //sw/device/silicon_creator/lib/ownership/keys/dummy:activate_key)
--next-application-key=$(location //sw/device/silicon_creator/lib/ownership/keys/dummy:app_prod_pub)
""",
test_harness = "//sw/host/tests/ownership:transfer_test",
),
rsa_key = {
"//sw/device/silicon_creator/lib/ownership/keys/dummy:app_prod": "app_prod",
},
deps = [
"//sw/device/lib/base:status",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib:boot_log",
"//sw/device/silicon_creator/lib/drivers:retention_sram",
],
)
2 changes: 1 addition & 1 deletion sw/device/silicon_creator/rom_ext/e2e/rescue/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ opentitan_test(
--exec="fpga load-bitstream {bitstream}"
--exec="bootstrap --clear-uart=true {firmware}"
# Set next slot via the rescue protocol
--exec="rescue boot-svc set-next-bl0-slot --next=SlotB"
--exec="rescue boot-svc set-next-bl0-slot --next=SlotB --get-response=false"
# Check for firmware execution in slot B
--exec="console --non-interactive --exit-success='bl0_slot = __BB\r\n' --exit-failure='{exit_failure}'"
# Reset and observe return to slot A.
Expand Down
1 change: 1 addition & 0 deletions sw/device/silicon_creator/rom_ext/e2e/verified_boot/BUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 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",
"DEFAULT_TEST_FAILURE_MSG",
Expand Down
3 changes: 3 additions & 0 deletions sw/host/opentitanlib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ rust_library(
"src/chip/boot_svc.rs",
"src/chip/helper.rs",
"src/chip/mod.rs",
"src/chip/rom_error.rs",
"src/console/mod.rs",
"src/console/spi.rs",
"src/crypto/ecdsa.rs",
Expand Down Expand Up @@ -259,6 +260,7 @@ rust_library(
"//third_party/openocd:jtag_cmsis_dap_adapter_cfg",
"//util/openocd/target:lowrisc-earlgrey.cfg",
"//util/openocd/target:lowrisc-earlgrey-lc.cfg",
"//sw/host/opentitanlib/bindgen:rom_error_enum",
],
crate_features = [
"include_hyperdebug_firmware",
Expand All @@ -275,6 +277,7 @@ rust_library(
"i2c_target": "$(location :i2c_target)",
"mem": "$(location :mem)",
"pinmux_config": "$(location :pinmux_config)",
"rom_error_enum": "$(location //sw/host/opentitanlib/bindgen:rom_error_enum)",
"spi_passthru": "$(location :spi_passthru)",
"ottf": "$(location :ottf)",
"hyperdebug_firmware": "$(location @hyperdebug_firmware//:hyperdebug/ec.bin)",
Expand Down
46 changes: 43 additions & 3 deletions sw/host/opentitanlib/bindgen/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

load("@rules_rust//bindgen:defs.bzl", "rust_bindgen_library")
load("@rules_rust//rust:defs.bzl", "rust_library")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("@rules_rust//bindgen:defs.bzl", "rust_bindgen", "rust_bindgen_library")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -187,6 +187,43 @@ rust_bindgen_library(
],
)

# We generate the bindgen source for rom_error_t so we can post-process it
# with the :rom_error_enum rule and build a full enum from all known
# rom_error_t values.
rust_bindgen(
name = "rom_error",
bindgen_flags = [
"--allowlist-type=rom_error_t",
],
cc_lib = "//sw/device/silicon_creator/lib:error",
header = "//sw/device/silicon_creator/lib:error.h",
)

# Generate a rust source file that contains the enum definition. This
# will get textual-included into opentitanlib's `chip::rom_error` module.
genrule(
name = "rom_error_enum",
srcs = [":rom_error"],
outs = ["rom_error_enum.rs"],
cmd = """
cat >$@ <<HEADER
with_unknown! {
pub enum RomError: u32 [default = Self::Unknown] {
HEADER

# The sed expression creates enumerators with idiomatic Rust names that
# refer to the bindgen'ed constants.
cat $(location :rom_error) \\
| grep const \\
| sed -E 's/^pub const (rom_error_kError([^:]+)).*$$/ \\2 = bindgen::rom_error::\\1,/g' >>$@

cat >>$@ <<FOOTER
}
}
FOOTER
""",
)

rust_bindgen_library(
name = "sram_program",
bindgen_flags = [
Expand Down Expand Up @@ -248,7 +285,10 @@ rust_bindgen_library(

rust_library(
name = "bindgen",
srcs = ["lib.rs"],
srcs = [
"lib.rs",
":rom_error",
],
deps = [
":alert",
":dif",
Expand Down
5 changes: 5 additions & 0 deletions sw/host/opentitanlib/bindgen/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ pub use multibits;
pub use sram_program;
pub use status;
pub use test_status;

#[allow(non_snake_case)]
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
pub mod rom_error;
7 changes: 7 additions & 0 deletions sw/host/opentitanlib/bindgen/rom_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// Note: The real `rom_error.rs` source file is automatically generated by
// the rom_error rule in the BUILD file. This file exists to prevent rustfmt
// from complaining that the source file doesn't exist.
30 changes: 17 additions & 13 deletions sw/host/opentitanlib/src/chip/boot_svc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::io::{Read, Write};

use super::ChipDataError;
use crate::chip::boolean::HardenedBool;
use crate::chip::rom_error::RomError;
use crate::crypto::ecdsa::{EcdsaPrivateKey, EcdsaPublicKey, EcdsaRawPublicKey, EcdsaRawSignature};
use crate::with_unknown;

Expand Down Expand Up @@ -86,7 +87,8 @@ pub struct MinBl0SecVerResponse {
/// The current minimum BL0 version.
pub ver: u32,
/// The status response to the request.
pub status: u32,
#[annotate(format = hex)]
pub status: RomError,
}

/// Request to set the next (one-time) owner stage boot slot.
Expand All @@ -102,7 +104,8 @@ pub struct NextBl0SlotRequest {
#[derive(Debug, Default, Serialize, Annotate)]
pub struct NextBl0SlotResponse {
/// The status response to the request.
pub status: u32,
#[annotate(format = hex)]
pub status: RomError,
/// The current primary slot.
pub primary_bl0_slot: BootSlot,
}
Expand All @@ -129,7 +132,8 @@ pub struct OwnershipUnlockRequest {
#[derive(Debug, Default, Serialize, Annotate)]
pub struct OwnershipUnlockResponse {
/// The status response to the request.
pub status: u32,
#[annotate(format = hex)]
pub status: RomError,
}

/// Request to activate ownership of the chip.
Expand All @@ -154,7 +158,8 @@ pub struct OwnershipActivateRequest {
#[derive(Debug, Default, Serialize, Annotate)]
pub struct OwnershipActivateResponse {
/// The status response to the request.
pub status: u32,
#[annotate(format = hex)]
pub status: RomError,
}

#[derive(Debug, Serialize, Annotate)]
Expand Down Expand Up @@ -373,15 +378,15 @@ impl TryFrom<&[u8]> for MinBl0SecVerResponse {
let mut reader = std::io::Cursor::new(buf);
Ok(MinBl0SecVerResponse {
ver: reader.read_u32::<LittleEndian>()?,
status: reader.read_u32::<LittleEndian>()?,
status: RomError(reader.read_u32::<LittleEndian>()?),
})
}
}
impl MinBl0SecVerResponse {
pub const SIZE: usize = 8;
pub fn write(&self, dest: &mut impl Write) -> Result<()> {
dest.write_u32::<LittleEndian>(self.ver)?;
dest.write_u32::<LittleEndian>(self.status)?;
dest.write_u32::<LittleEndian>(u32::from(self.status))?;
Ok(())
}
}
Expand Down Expand Up @@ -410,16 +415,15 @@ impl TryFrom<&[u8]> for NextBl0SlotResponse {
fn try_from(buf: &[u8]) -> std::result::Result<Self, Self::Error> {
let mut reader = std::io::Cursor::new(buf);
Ok(NextBl0SlotResponse {
status: reader.read_u32::<LittleEndian>()?,
status: RomError(reader.read_u32::<LittleEndian>()?),
primary_bl0_slot: BootSlot(reader.read_u32::<LittleEndian>()?),
})
}
}
impl NextBl0SlotResponse {
pub const SIZE: usize = 4;
pub fn write(&self, dest: &mut impl Write) -> Result<()> {
dest.write_u32::<LittleEndian>(self.status)?;
dest.write_u32::<LittleEndian>(u32::from(self.primary_bl0_slot))?;
dest.write_u32::<LittleEndian>(u32::from(self.status))?;
Ok(())
}
}
Expand Down Expand Up @@ -472,14 +476,14 @@ impl TryFrom<&[u8]> for OwnershipUnlockResponse {
fn try_from(buf: &[u8]) -> std::result::Result<Self, Self::Error> {
let mut reader = std::io::Cursor::new(buf);
Ok(OwnershipUnlockResponse {
status: reader.read_u32::<LittleEndian>()?,
status: RomError(reader.read_u32::<LittleEndian>()?),
})
}
}
impl OwnershipUnlockResponse {
pub const SIZE: usize = 4;
pub fn write(&self, dest: &mut impl Write) -> Result<()> {
dest.write_u32::<LittleEndian>(self.status)?;
dest.write_u32::<LittleEndian>(u32::from(self.status))?;
Ok(())
}
}
Expand Down Expand Up @@ -527,14 +531,14 @@ impl TryFrom<&[u8]> for OwnershipActivateResponse {
fn try_from(buf: &[u8]) -> std::result::Result<Self, Self::Error> {
let mut reader = std::io::Cursor::new(buf);
Ok(OwnershipActivateResponse {
status: reader.read_u32::<LittleEndian>()?,
status: RomError(reader.read_u32::<LittleEndian>()?),
})
}
}
impl OwnershipActivateResponse {
pub const SIZE: usize = 4;
pub fn write(&self, dest: &mut impl Write) -> Result<()> {
dest.write_u32::<LittleEndian>(self.status)?;
dest.write_u32::<LittleEndian>(u32::from(self.status))?;
Ok(())
}
}
4 changes: 2 additions & 2 deletions sw/host/opentitanlib/src/chip/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::fs::File;
use std::io::Read;
use std::path::PathBuf;

#[derive(Debug, Args)]
#[derive(Debug, Default, Args)]
pub struct OwnershipUnlockParams {
#[arg(long, value_enum, help = "Requested unlock mode")]
pub mode: Option<UnlockMode>,
Expand Down Expand Up @@ -63,7 +63,7 @@ impl OwnershipUnlockParams {
}
}

#[derive(Debug, Args)]
#[derive(Debug, Default, Args)]
pub struct OwnershipActivateParams {
#[arg(long, value_parser = u64::from_str, help="Current ROM_EXT nonce")]
pub nonce: Option<u64>,
Expand Down
1 change: 1 addition & 0 deletions sw/host/opentitanlib/src/chip/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod boolean;
pub mod boot_log;
pub mod boot_svc;
pub mod helper;
pub mod rom_error;

#[derive(Debug, Error)]
pub enum ChipDataError {
Expand Down
7 changes: 7 additions & 0 deletions sw/host/opentitanlib/src/chip/rom_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use crate::with_unknown;

include!(env!("rom_error_enum"));
7 changes: 7 additions & 0 deletions sw/host/opentitanlib/src/crypto/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@ impl TryFrom<&EcdsaPublicKey> for EcdsaRawPublicKey {
}
}

impl TryFrom<EcdsaPublicKey> for EcdsaRawPublicKey {
type Error = Error;
fn try_from(v: EcdsaPublicKey) -> Result<Self, Self::Error> {
EcdsaRawPublicKey::try_from(&v)
}
}

impl FromStr for EcdsaRawPublicKey {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand Down
Loading
Loading