Code Monkey home page Code Monkey logo

caliptra-sw's People

Contributors

ajisaxena avatar amd-isaac avatar andreslagarcavilla avatar arthurheymans avatar attzonko avatar benjamindoron avatar bluegate010 avatar ericeilertson avatar fdamato avatar ferralcoder avatar github-actions[bot] avatar jameszhang-nvidia avatar jhand2 avatar jlmahowa-amd avatar korran avatar leongross avatar mhatrevi avatar nquarton avatar premalathak12 avatar rkr35 avatar rusty1968 avatar satyamsetti avatar sphinxc0re avatar sree-revoori1 avatar srinathshiv avatar steven-bellock avatar vmhatre avatar vsonims avatar wmaroneamd avatar zhalvorsen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

caliptra-sw's Issues

FIPS module init

Placeholder until we get more clarity from FIPS certifiability assessment

EnvCell::map is unsound

EnvCell::map allows multiple aliasing &mut references to the same memory location to be created from a safe module, which is unsound.

#[test]
fn unsound_envcell() {
    let cell: EnvCell<u32> = EnvCell::new(42);
    cell.map(|ref0: &mut u32| {
        cell.map(|ref1: &mut u32| {
            // Soundness violation: ref0 and ref1 both point to the same memory location
            assert_eq!(ref0 as *mut u32, ref1 as *mut u32);
        })
    });
}
$ cargo +nightly miri test -p caliptra-rom unsound_envcell
unning 1 test
test env_cell::test::unsound_envcell ... error: Undefined Behavior: not granting access to tag <184548> because that would remove [Unique for <184541>] which is strongly protected because it is an argument of call 51579
  --> rom/dev/src/env_cell.rs:39:26
   |
39 |         closure(unsafe { &mut *self.val.get() })
   |                          ^^^^^^^^^^^^^^^^^^^^ not granting access to tag <184548> because that would remove [Unique for <184541>] which is strongly protected because it is an argument of call 51579
   |
   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
   = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <184548> was created by a SharedReadWrite retag at offsets [0x0..0x4]
  --> rom/dev/src/env_cell.rs:39:32
   |
39 |         closure(unsafe { &mut *self.val.get() })
   |                                ^^^^^^^^^^^^^^
help: <184541> is this argument
  --> rom/dev/src/env_cell.rs:35:29
   |
35 |     pub fn map<F, R>(&self, closure: F) -> R
   |                             ^^^^^^^
   = note: BACKTRACE (of the first span):
   = note: inside `env_cell::EnvCell::<u32>::map::<[closure@rom/dev/src/env_cell.rs:61:22: 61:38], ()>` at rom/dev/src/env_cell.rs:39:26: 39:46
note: inside closure
  --> rom/dev/src/env_cell.rs:61:13
   |
61 | /             cell.map(|ref1: &mut u32| {
62 | |                 // Soundness violation: ref0 and ref1 both point to the same memory location
63 | |                 assert_eq!(ref0 as *mut u32, ref1 as *mut u32);
64 | |             })
   | |______________^
note: inside `env_cell::EnvCell::<u32>::map::<[closure@rom/dev/src/env_cell.rs:60:18: 60:34], ()>`
  --> rom/dev/src/env_cell.rs:39:9
   |
39 |         closure(unsafe { &mut *self.val.get() })
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `env_cell::test::unsound_envcell`
  --> rom/dev/src/env_cell.rs:60:9
   |
60 | /         cell.map(|ref0: &mut u32| {
61 | |             cell.map(|ref1: &mut u32| {
62 | |                 // Soundness violation: ref0 and ref1 both point to the same memory location
63 | |                 assert_eq!(ref0 as *mut u32, ref1 as *mut u32);
64 | |             })
65 | |         });
   | |__________^
note: inside closure
  --> rom/dev/src/env_cell.rs:58:26
   |
57 |     #[test]
   |     ------- in this procedural macro expansion
58 |     fn unsound_envcell() {
   |                          ^
   = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)

Propose hybrid (LMS + ECDSA) signing for FMC and Runtime

One goal of Caliptra is to provide a firmware signing scheme for defending against attacks from quantum computers. Currently, only stateful PQC signing algorithms are approved by NIST. Caliptra has chosen to use LMS for firmware signing. Caliptra also supports ECDSA P-384 signing schemes. We need to decide which of these verification schemes will be used in which cases.

Proposal

I propose that Caliptra should support multiple possible modes of signature verification.

Why

  • Maintaining LMS signing infrastructure is new for most of the industry and is a bit non-trivial to get right (requires carefully managing state to avoid leaking key material).
  • Leaking key material probably means a respin
  • Adding an ECDSA signature is pretty trivial and mitigates the risk quite a bit. In a pre-PQC world, leaking the XMSS key isn't the end of the world since we have an ECDSA backstop. I think this would be prudent for v1 (and we can discuss simplifying in future versions once we're confident everything works well).

Key Manifest Changes

The key manifest may contain all of

  • Up to 4 ECDSA manufacturer public keys
  • Up to 4 LMS manufacturer public keys

Assuming P-384 ECDSA keys and SHA384 LMS keys, at most, this adds 192 bytes compared to only-ECDSA or only-LMS.

This manifest is:

  • Hashed and stored in fuses
  • Included in every firmware image header (and compared to the value in fuses)

Firmware image changes

A firmware image header may contain all of

  • Manufacturer ECDSA signature
  • Manufacturer LMS signature
  • Owner ECDSA public key
  • Owner ECDSA signature
  • Owner LMS public key
  • Owner LMS signature

In this case, LMS signatures are much larger than ECC signatures. The overhead of including both (instead of just LMS) is minimal.

Modes

Which signatures are enforced by ROM needs to be configurable because LMS signers may not be ready until after tape-out. A public key in can be included in the fused manifest, but LMS signatures may not be available to sign images until some later time.

Note: If a manufacturer ever wants to support hybrid signing, both the ECDSA and LMS public keys must be present in the fused manifest at tape-out.

I propose a single configuration fuse bit:

If fuse is 0, use Mode 1
If fuse is 1, use Mode 2

Notably, once Caliptra is fused to do LMS verification, it cannot be fused to stop doing LMS.

Mode 1: ECDSA-only

  • ROM only enforces the manufacturer ECDSA signature
  • FMC only enforces the Owner ECDSA signature

Mode 2: Hybrid signing

  • ROM enforces both the manufacturer LMS signature and manufacturer ECDSA signature
  • FMC enforces both the Owner LMS signature and Owner ECDSA signature

Error code collisions caused by 8-bit overflow

From what I can tell, Caliptra 32-bit error codes are intended to be an 8-bit "component id" in high bits and a 24-bit "error code" in the low bits.

((($crate::error::RomComponent::$comp_name) as Self) << 24) | (val as Self)

Unfortunately, some of the component ids overflow 8 bits:

/// Caliptra Component
pub enum RomComponent {
/// Initial Device ID Layer
InitDevId = 0x100,
/// Local Device ID Layer
LocalDevId = 0x101,
/// FMC Alias Layer
FmcAlias = 0x102,
/// Global Error
Global = 0x103,
}

#[test]
fn test_error_value() {
    let error_code: u32 = GlobalErr::Exception.into();
    // Would be 0x1_0300_0002 without overflow
    assert_eq!(error_code, 0x0300_0002);
}

This results in a error-space collision:

#[test]
fn test_error_value() {
    let error_code: u32 = Sha384Err::ReadDataKvWrite.into();
    // Collides with GlobalErr::Exception
    assert_eq!(error_code, 0x0300_0002);
}

Handoff table Indexes can't fully describe the storage entry address in the data vault (lossy conversion)

The address of an entry stored in the data vault is a pair (entry_type, entry_variant) , where entry type can be WarmResetEntry4, ColdResetEntry48, The entry type is an abstraction of the register type (sticky/non-sticky/scratch)

The entry type information is lost when conversion entry_type::entry_variant to u8 is performed forcing FMC to make assumptions about the entry type where the information is stored and defeating the purpose of a handoff table to decouple FMC and ROM.

Example :
rt_fw_load_addr_idx: WarmResetEntry4::RtLoadAddr.into(),
fmc_pub_key_x_dv_idx: ColdResetEntry48::FmcPubKeyX.into()

pub enum WarmResetEntry4 {
RtSvn = 0,
RtLoadAddr = 1,
RtEntryPoint = 2,
ManifestAddr = 3,
}
pub enum ColdResetEntry48 {
LDevDiceSigR = 0,
LDevDiceSigS = 1,
LDevDicePubKeyX = 2,
LDevDicePubKeyY = 3,
FmcDiceSigR = 4,
FmcDiceSigS = 5,
FmcPubKeyX = 6,
FmcPubKeyY = 7,
FmcTci = 8,
OwnerPubKeyHash = 9,
}

pub enum ColdResetEntry4 {
FmcSvn = 0,
FmcLoadAddr = 1,
FmcEntryPoint = 2,
VendorPubKeyIndex = 3,
}

Report all FMC-relevant evidence in the FMC alias certificate

Currently, the following information is used to derive the FMC CDI:

  • Lifecycle state
  • Debug lock state
  • Anti-rollback disable state
  • Vendor public key hash
  • Owner public key hash
  • Vendor ECC public key index
  • FMC hash
  • FMC SVN

However, only the following information is placed as evidence in the FMC alias certificate:

  • FMC hash
  • Owner public key hash

These two lists should be consistent. Any data used to derive the CDI, but not placed in the certificate over the resulting public key, cannot functionally be attested.

There are some options:

  1. Add a third digest to the alias certificate, which represents a hash of all the data in the first bullet list. The two existing digests are present only as a matter of convenience.
  2. Remove the two existing digests in favor of a single digest over all data in the first bullet list.
  3. Leave the FMC hash digest in place in the cert, and repurpose the other digest to be over all data in the first bullet list.

Option 1 presents a complication: we will need some way to ferry the new hash from ROM to FMC. For the other data in the certificate, this is currently done by way of Data Vault slots. However, we are currently at capacity for Data Vault slots. We would need to modify RTL to allocate at least one more digest-sized slot to hold this new information that FMC will need to reconstitute the certificate.

Alternatively, we could stash this data in a PCR. The issue there is that the data that FMC pulls out and places in the certificate will not be SHA384(...); rather, it will be SHA384(0x0000 || SHA384(...)) - the result of a hash extend.

One other option would be to expand the handoff table structure to include this new data. There is no special reason for the data to be locked away in a Data Vault slot. If it mutates after ROM uses it, the certificate that FMC reconstitutes will not have a valid signature.

Refactor Mailbox Driver Drop Trait Implementation

The drop trait implementation needs to be unwrap free. Currently the Mailbox Drop implementation is panicking due to unwraps. We should not be making any calls that results in unwraps to be called.

FMC Task - FHT Sanity Check

FMC validates FHT marker field and that it has valid pointers and indices for the rest of the elements it requires to be passed from ROM

ROM Task - support measurement command

Problem statement: SoCs may have ROM patches and firmware that they need to boot before Caliptra firmware. Want to submit those measurements to Caliptra before execution.

Solution:

  • Caliptra ROM will add a mailbox command for storing measurement.
  • Caliptra ROM will support this command prior to CALIPTRA_FW_LOAD command.
  • Caliptra ROM will use these measurements to derive CDI.
  • Caliptra ROM will store those measurements to either PCRs or to Data Vault (set of write lockable registers on pwrgood reset). Vishal prefers Data Vault because PCRs don't support write locking, but write locking is not a strict requirement.

Centralized Error Code Registry for Caliptra Components

Diagnostic and error reporting capability should reside in a common crate with all the caliptra error codes, that can be referenced from test cases and caliptra clients, including a Debug impl when compiled with the std feature.

The error namespace shall be partitioned to avoid collisions and enable better failure diagnostics

FMC Task - Create Runtime shell

Dummy runtime module initially for use in development and testing of FMC but can be built out into the real runtime module as well.

FMC Task - Basic Test

Create basic test firmware to be used to simulate load and execution of FMC FW module.
Further down the road, this will also be used to unit-test sub-flows and functions as they are added.

[feature] Implement LMS hybrid signing

The is currently an PR (#99) out for implementing an LMS driver. Some additional things we will need:

ROM:

  • Use LMS revocation fuses during verification
  • Check LMS hybrid fuse to decide whether to do ECDSA-only or hybrid
  • Update image header code to process LMS keys/signatures

Emulator:

  • Add fuses in sw emulator

Spec:

  • Update the image header format and verification spec to include hybrid signing

Does Runtime require a panic handler?

Runtime specification seems to call for a panic handler as part of its mailbox command error handling flow, but we have tests in place to detect if panic symbol is included .

A mailbox command can fail to complete in a couple ways

Hang/timeout which results in the watchdog firing
Unrecoverable panic
In both these cases, the panic handler will write diagnostic panic information to registers readable by the SoC, firmware will undergo impactless reset, and mailbox_data_avail will be asserted.

hmac384::test_hmac3 fails with latest caliptra-rtl

With the old RTL, no problem...

$ git checkout main
$ (cd hw-latest/caliptra-rtl/ && git log -2 --oneline)
6b69da9 (HEAD) Fix AHB multiplexing issue: #20
01fcfd1 Initial Pre0p8 release from dev-msft (#9)
$ export CXX="ccache g++"
$ cargo test --release --features=verilator -p caliptra-lib test_hmac384
<snip>
hmac384::test_kat...    [ok]
hmac384::test_hmac0...  [ok]
hmac384::test_hmac1...  [ok]
test test_hmac384 has been running for over 60 seconds
hmac384::test_hmac3...  [ok]
<snip>

With the new RTL...

$ git checkout rtl-2023-03-27
$ (cd hw-latest/caliptra-rtl/ && git log -8 --oneline)
cdd9afa (HEAD, ahb-mux-fix) Fix AHB multiplexing issue: #20
fa91d66 (main) Merge pull request #27 from chipsalliance/dev-integrate
f47d19d Sync from MSFT Internal repo w/ TRNG, HMAC SCA, PCR Hash/sign, Env Var rename (#21)
e5c1b48 Checking in a copy of the opentitan repository taken at (#22)
3678553 Adding verilator CI smoke test (#19)
b19f4ff Add Register docs links to README.md (#13)
01fcfd1 Initial Pre0p8 release from dev-msft (#9)
$ cargo test --release --features=verilator -p caliptra-lib test_hmac384
hmac384::test_kat...    [ok]
hmac384::test_hmac0...  [ok]
hmac384::test_hmac1...  [ok]
test test_hmac384 has been running for over 60 seconds
hmac384::test_hmac3...  [failed]
Error: panicked at 'assertion failed: `(left == right)`
  left: `Array4xN([1097496930, 177872290, 3861325564, 3222974378, 3615216998, 3373329619, 1992284781, 2272737848, 311909870, 2326523809, 2038415403, 775445936])`,
 right: `Array4xN([3806224643, 3931861133, 1050772493, 1774245656, 4173031246, 1110546316, 4049204051, 1657138985, 2965254665, 1955743625, 2383417612, 2640588215])`', drivers/test-fw/src/bin/hmac384_tests.rs:122:5

* TESTCASE FAILED

The test case does the following:

fn test_hmac3() {
    //
    // Step 1: Place a key in the key-vault.
    //
    let seed = [0u8; 48];
    let mut key_usage = KeyUsage::default();
    key_usage.set_hmac_key(true);
    let key_out_1 = KeyWriteArgs {
        id: KeyId::KeyId0,
        usage: key_usage, // hmac_key
    };
    let result = Ecc384::default().key_pair(
        Ecc384Seed::from(&Ecc384Scalar::from(seed)),
        Ecc384PrivKeyOut::from(key_out_1),
    );
    assert!(result.is_ok());

    //
    // Step 2: Hash the data with the key from key-vault.
    // Key is [0xc9, 0x8, 0x58, 0x5a, 0x48, 0x6c, 0x3b, 0x3d, 0x8b, 0xbe, 0x50, 0xeb, 0x7d, 0x2e, 0xb8, 0xa0,
    //         0x3a, 0xa0, 0x4e, 0x3d, 0x8b, 0xde, 0x2c, 0x31, 0xa8, 0xa2, 0xa1, 0xe3, 0x34, 0x9d, 0xc2, 0x1c,
    //         0xbb, 0xe6, 0xc9, 0xa, 0xe2, 0xf7, 0x49, 0x12, 0x88, 0x84, 0xb6, 0x22, 0xbb, 0x72, 0xb4, 0xc5,];
    //
    let data: [u8; 8] = [0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65];

    let result: [u8; 48] = [
        0xe2, 0xde, 0x61, 0x3, 0xea, 0x5b, 0x70, 0x8d, 0x3e, 0xa1, 0x84, 0xd, 0x69, 0xc0, 0xd7,
        0x18, 0xf8, 0xbb, 0x67, 0x4e, 0x42, 0x31, 0x97, 0x8c, 0xf1, 0x59, 0xf3, 0x53, 0x62, 0xc5,
        0xef, 0x29, 0xb0, 0xbe, 0x32, 0x9, 0x74, 0x92, 0x47, 0x89, 0x8e, 0x10, 0x11, 0xc, 0x9d,
        0x64, 0x2d, 0xb7,
    ];

    let mut out_tag = Array4x12::default();
    let key = KeyReadArgs::new(KeyId::KeyId0);
    let actual = Hmac384::default().hmac(key.into(), (&data).into(), (&mut out_tag).into());

    assert!(actual.is_ok());
    assert_eq!(out_tag, Array4x12::from(result));
}

It's not clear to me whether the test-case or the RTL is faulty.

Error recovery policy for boot flow

          Don't need to decide in this PR, but if something fails during boot we probably want to do one of
  1. Try again to boot from rom (maybe invoke an impactless reset?)
  2. Notify the SoC and then wait for a new firmware image

This is probably something to discuss with the group.

Originally posted by @jhand2 in #135 (comment)

FMC Task - Implement DICE flow

FMC must:

  1. Derive Runtime CDI
  2. Derive Runtime Alias Key Pair
  3. Certify Runtime Alias Pub Key

Implementation should follow example of ROM implementation, as it may be possible to combine some of this code into common functions in the future.

Mailbox driver does not detect incoming messages correctly

From https://github.com/chipsalliance/caliptra-rtl/blob/main/docs/Caliptra_Integration_Specification.pdf:

9.3 Sender Protocol

Sending data to the mailbox:

  1. Requester queries the mailbox by reading the LOCK control register.
    • If LOCK returns 0, LOCK is granted and will be set to 1.
    • If LOCK returns 1, MBOX is locked for another device.
  2. Requester writes the command to the COMMAND register.
  3. Requester writes the data length in bytes to the DLEN register.
  4. Requester writes data packets to the MBOX DATAIN register.
  5. Requester writes to the EXECUTE register.
  6. Requester reads the STATUS register. Status can return:
    • CMD_BUSY - 2’b00 – Indicates the requested command is still in progress
    • DATA_READY - 2’b01 – Indicates the return data is in the mailbox for requested command
    • CMD_COMPLETE- 2’b10 – Indicates the successful completion of the requested command
    • CMD_FAILURE- 2’b11 – Indicates the requested command failed
  7. Requester reads the response if DATA_READY was the status.
  8. Requester resets the EXECUTE register to release the lock.

9.4 Receiver Protocol

Upon receiving indication that mailbox has been populated, the appropriate device can read the
mailbox. This is indicated by a dedicated wire that is asserted when Caliptra populates the mailbox for SoC consumption.Receiving data from the mailbox:

  1. On mailbox_data_avail assertion, the receiver reads the COMMAND register.
  2. Receiver reads the DLEN register.
  3. Receiver reads the MBOX DATAOUT register.
    • Continue reading MBOX DATAOUT register until DLEN bytes are read.
  4. If a response is required, receiver can populate the mailbox with the response by writing DATAIN
  5. Set the mailbox status register to hand control back to the sender to read the response
  6. The sender will reset the EXECUTE register after reading the response.
    • This releases the LOCK on the mailbox.

See this code in the mailbox driver:

/// Attempts to start receiving data by checking the status.
/// # Returns
/// * 'MailboxRecvTxn' - Object representing a receive operation
pub fn try_start_recv_txn(&self) -> Option<MailboxRecvTxn> {
let mbox = mbox::RegisterBlock::mbox_csr();
match mbox.status().read().status() {
MboxStatusE::DataReady => Some(MailboxRecvTxn::default()),
_ => None,
}
}

This is incorrect. Nowhere in section 9.4 do the docs mention a receiver reading the status field, which is only used to notify the original sender (the SoC) of the result. The driver should not be looking at mbox.status().read().status(), but instead mbox.status().read().mbox_fsm_ps() == MboxFsmE::MboxExecuteUc, which becomes true after the SoC sets the execute bit. (The docs say to use the interrupt, but I can't find docs stating which interrupt line comes from the mailbox, and the fsm state field seems to work well enough).

Because of this mistake, tests pretending to be the SoC are setting the data-ready bit manually, which is also incorrect:

// Set the status as DATA_READY.
let _ = mailbox.set_status_data_ready();
// Set the execute register.
let _ = mailbox.write_execute(1);

// Set the status as DATA_READY.
self.soc_mbox()
.status()
.write(|w| w.status(|w| w.data_ready()));
// Set Execute Bit
self.soc_mbox().execute().write(|w| w.execute(true));

All this has to be fixed, and the emulator needs to be modified to behave the same as the RTL.

Caliptra model for SoC Cmodel

NVIDIA uses an SoC C-model to do code development and validation for fullchip collateral. We would want to integrate a Caliptra model of the external registers https://ereg.caliptra.org for the boot process and the SoC ROM code to develop against.

@nstewart-amd had proposed a similar problem statement to @korran and @vsonims during December meet-up. Unclear whether there was a follow-up, so filing the ticket.

Should Caliptra DICE certificates expire?

A discussion came up in #7 about whether Caliptra DPE and DICE certificates should expire. Opening this issue to have a longer discussion and unblock #7.

I think a few questions need answering:

  1. Should DPE certs expire?
  2. Should any DICE certs expire?
  3. If yes to either 1 or 2, what will be the machanism?

Capturing some of that discussion:

From @Bryankel

In certificate-based cryptography, certificates have a validity period that manages the life cycle of the certificate. The validity period is important for PKI revocation to work effectively. The PKI CRL maintains a list of revoked certificates within a window of a given certificate validity period. In x509 PKI, the CRL is pruned based on this certificate validity sliding window. If certificates do not have a reasonable validity period will quickly become unmanageable at scale, as the CRL would grow indefinitely.

In having indefinite certificates it eliminates interoperability with most PKI systems and their revocation mechanisms. The alternative is every Caliptra needs to have a dedicated offline CA that can be revoked, this is heavy burden on PKI infra.

Some open questions if we did make certificates expire:

  • What mechanism would we use to set the expiration date?
  • There is a proposal to certify FMC Alias Cert with an external CA. Can expiration be handled at this layer? If FMC Alias Cert expires, all downstream DICE certs (including DPE certs) will be revoked.

One possible mechanisms discussed in #7: Owner-signed blob in the firmware image with the expiration value.

Proposal for whole-soc attestation with Caliptra

Problem

For Caliptra, DICE and DPE provide the basis for attestation. This provides software oracle access to a signing key derived from measurements up-to and including that component. This is generally useful for signing attestations but has one limitation; to attest the whole SoC with DPE you would need to challenge all the leaf keys on the SoC and parse their certificates. This is prohibitively challenging for providing a single point for getting all the measurements for the SoC. To accomplish this, we propose the following.

SoC Manager SPDM Responder

In SoC integrations, we expect an SoC Manager to implement an SPDM Responder. SoC Manager firmware is measured into Caliptra DPE during SoC ROM boot. This provides SoC Manager with an identity that it cannot forge (SoC Manager Alias).

It can populate SPDM measurement blocks by retrieving tagged measurements from DPE/Caliptra (see below).

DPE primitives

DPE provides the following commands to help here:

  • TagTci: Tag a specific DPE measurement so it can be looked up later
  • GetTaggedTci: Look up a previously tagged measurement

During SoC boot/execution, any measurements made into DPE that the SoC manager wishes to report for whole-soc attestation will be tagged:

tagged-dpe

Any SoC entity can then retrieve these measurements (including both current and journey measurements).

Why can't SoC manager lie about SPDM measurements?

SoC manager gets measurements from DPE unsigned and then reports them via SPDM. Why can't it lie?

This is because SoC Manager Alias Cert contains SoC manager firmware measurements and roots back to Caliptra's DICE identity. A malicious SoC Manager reporting bad SPDM measurements can be found out when validating its Alias Certificate.

API Choice Rationale

Any signing oracle Caliptra exposes should map to an industry standard API, which will ease integration with datacenter attestation flows and middleware routing protocols such as Redfish. As Caliptra Core does not expose an SPDM Responder, it is preferable for these measurements to be encapsulated within an SPDM message constructed by an SoC Manager, rather than encapsulated within a custom Caliptra-defined structure that does not map to any existing standard attestation protocol. Note also that DPE measurements form a tree structure, rather than a linear list of PCRs. Each integration will construct this tree in a different manner; Caliptra is agnostic as to the tree's structure. The mechanism proposed above enables an SoC Manager to present measurements from the tree in whatever manner makes the most sense for a given integration.

Enumerate runtime firmware usage of shared resources

The Runtime Firmware specification should define usage of some shared Caliptra resources. In particular:

  • DCCM usage. Especially DCCM which must persist across impactless update
  • KeyVault slot usage (by index)
  • PCR usage (by index)
  • Timeout values for watchdog/mailbox commands
  • How diagnostic registers will be populated on panic

Define clear steps to lock/unlock FMC secrets across reset and update flows

Created this issue to track open conversation in this PR: #8

jhand2 2 weeks ago
We probably need to reuse this key on impactless reset right? So to avoid rederiving the Private key probably need to cache in in keyvault and lock it. Not sure what the mechanisms are for locking/unlocking slots.

Member
Author
@FerralCoder FerralCoder 2 weeks ago
You may be right, I am waiting to see the final definition of the hardware capabilities before I add in more specific details about hitless update. This is captured as a "ToDo" item at the bottom of the doc.

Member
@JohnTraverAmd JohnTraverAmd last week
@jhand2 The KeyVault is not accessible by FW. The keys can be referenced/used by FW, but not read. When you say Locking, what do you want locked?

Member
@jhand2 jhand2 last week
I mean locking from use. We need to be able to use this key in FMC during impactless resets, but we don't want Runtime Firmware to be able to use it. Not sure if KeyVault can lock things from use until next impactless reset.

In theory you could just re-derive the key, but there might be FIPS concern there. Not sure.

Member
@Bryankel Bryankel last week
The current architecture preserves across resets. In the current architecture the ROM cannot rederive the FMC UDS, it must preserve it in the KV. The fused entropy that's the UDS is only transiently available on cold boot.

Member
@jhand2 jhand2 last week
If preserved in KV, can we prevent runtime firmware from using it?

Member
@Bryankel Bryankel last week
It gets locked by ROM

Member
@jhand2 jhand2 last week
Cool, just wanted to make sure we have a mechanism in hardware to lock/unlock.

Member
Author
@FerralCoder FerralCoder 18 hours ago
It needs to be locked by FMC, not ROM. Otherwise FMC will not be able to use it to certify RT

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.