Skip to content

Commit

Permalink
[ownership] Include ApplicationKey constraints
Browse files Browse the repository at this point in the history
Include the `usage_constraint` field from ApplicationKeys into the
overall constraint requirement.

Signed-off-by: Chris Frantz <[email protected]>
(cherry picked from commit 49b46a7)
  • Loading branch information
cfrantz authored and moidx committed Nov 5, 2024
1 parent f5a00e7 commit 9204c41
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 3 deletions.
7 changes: 7 additions & 0 deletions sw/device/silicon_creator/rom_ext/e2e/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ otp_json(
},
lock = True,
),
otp_partition(
name = "HW_CFG",
items = {
"DEVICE_ID": "0000000011111111222222223333333344444444555555556666666600010001",
},
lock = True,
),
],
visibility = ["//visibility:private"],
)
Expand Down
56 changes: 56 additions & 0 deletions sw/device/silicon_creator/rom_ext/e2e/ownership/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ load(
"//sw/device/silicon_creator/rom_ext/e2e/ownership:defs.bzl",
"ownership_transfer_test",
)
load("//rules:const.bzl", "CONST", "hex")
load("//rules:manifest.bzl", "manifest")

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

Expand Down Expand Up @@ -58,6 +60,20 @@ opentitan_binary(
],
)

# This manifest is node-locked to the DEVICE_ID provided by the ROM_EXT E2E OTP
# configuration //sw/device/silicon_creator/rom_ext/e2e:otp_img_secret2_locked_rma,
# and required by the exec_env `fpga_hyper310_rom_ext`.
manifest({
"name": "nodelocked_manifest",
"identifier": hex(CONST.OWNER),
"device_id": [
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
hex(0x66666666),
hex(0x55555555),
],
"visibility": ["//visibility:public"],
})

# rom_ext_e2e_testplan.hjson%rom_ext_e2e_transfer_any_test
ownership_transfer_test(
name = "transfer_any_test",
Expand All @@ -84,6 +100,46 @@ ownership_transfer_test(
],
)

ownership_transfer_test(
name = "bad_appkey_constraint_test",
fpga = fpga_params(
changes_otp = True,
test_cmd = """
--clear-bitstream
--bootstrap={firmware}
--unlock-mode=Any
--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_ecdsa_pub)
--config-kind=with-app-constraint
--expected-error=SigverifyBadEcdsaSignature
""",
test_harness = "//sw/host/tests/ownership:transfer_test",
),
)

ownership_transfer_test(
name = "good_appkey_constraint_test",
fpga = fpga_params(
changes_otp = True,
test_cmd = """
--clear-bitstream
--bootstrap={firmware}
--unlock-mode=Any
--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_ecdsa_pub)
--config-kind=with-app-constraint
""",
test_harness = "//sw/host/tests/ownership:transfer_test",
),
manifest = ":nodelocked_manifest",
)

# rom_ext_e2e_testplan.hjson%rom_ext_e2e_bad_unlock_test
ownership_transfer_test(
name = "bad_unlock_test",
Expand Down
2 changes: 2 additions & 0 deletions sw/device/silicon_creator/rom_ext/e2e/ownership/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def ownership_transfer_test(
ecdsa_key = {
"//sw/device/silicon_creator/lib/ownership/keys/dummy:app_prod_ecdsa": "app_prod",
},
manifest = None,
data = [
"//sw/device/silicon_creator/lib/ownership/keys/dummy:activate_key",
"//sw/device/silicon_creator/lib/ownership/keys/dummy:app_prod_ecdsa_pub",
Expand Down Expand Up @@ -43,6 +44,7 @@ def ownership_transfer_test(
srcs = srcs,
exec_env = exec_env,
ecdsa_key = ecdsa_key,
manifest = manifest,
data = data,
defines = defines,
deps = deps,
Expand Down
5 changes: 2 additions & 3 deletions sw/device/silicon_creator/rom_ext/rom_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,8 @@ static rom_error_t rom_ext_verify(const manifest_t *manifest,
hmac_sha256_init();
// Hash usage constraints.
manifest_usage_constraints_t usage_constraints_from_hw;
// TODO(cfrantz): Combine key's usage constraints with manifest's
// usage_constraints.
sigverify_usage_constraints_get(manifest->usage_constraints.selector_bits,
sigverify_usage_constraints_get(manifest->usage_constraints.selector_bits |
keyring.key[verify_key]->usage_constraint,
&usage_constraints_from_hw);
hmac_sha256_update(&usage_constraints_from_hw,
sizeof(usage_constraints_from_hw));
Expand Down
10 changes: 10 additions & 0 deletions sw/host/tests/ownership/transfer_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ const CFG_RESCUE1: u32 = 0x0000_0008;
// Request a rescue configuration that restricts the set of allowed commands
// (e.g. this one removes "SetNextBl0Slot" from the set of allowed commands).
const CFG_RESCUE_RESTRICT: u32 = 0x0000_0010;
// Request a configuration where the application key has a usage constraint.
const CFG_APP_CONSTRAINT: u32 = 0x0000_0020;

#[repr(u32)]
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, ValueEnum)]
Expand All @@ -131,6 +133,7 @@ pub enum OwnerConfigKind {
WithFlashLocked = CFG_FLASH1 | CFG_RESCUE1 | CFG_FLASH_LOCK,
WithRescue = CFG_RESCUE1,
WithRescueRestricted = CFG_FLASH1 | CFG_RESCUE1 | CFG_RESCUE_RESTRICT,
WithAppConstraint = CFG_APP_CONSTRAINT,
}

impl OwnerConfigKind {
Expand Down Expand Up @@ -198,13 +201,20 @@ where
let activate_key = EcdsaPrivateKey::load(activate_key)?;
let unlock_key = EcdsaPrivateKey::load(unlock_key)?;
let app_key = EcdsaPublicKey::load(app_key)?;
let constraint = if config & CFG_APP_CONSTRAINT == 0 {
0
} else {
// Constrain to the DIN field of device_id.
0x6
};
let mut owner = OwnerBlock {
ownership_key_alg: OwnershipKeyAlg::EcdsaP256,
owner_key: KeyMaterial::Ecdsa(owner_key.public_key().try_into()?),
activate_key: KeyMaterial::Ecdsa(activate_key.public_key().try_into()?),
unlock_key: KeyMaterial::Ecdsa(unlock_key.public_key().try_into()?),
data: vec![OwnerConfigItem::ApplicationKey(OwnerApplicationKey {
key_alg: OwnershipKeyAlg::EcdsaP256,
usage_constraint: constraint,
key_domain: ApplicationKeyDomain::Prod,
key: KeyMaterial::Ecdsa(app_key.try_into()?),
..Default::default()
Expand Down

0 comments on commit 9204c41

Please sign in to comment.