Skip to content

Commit

Permalink
Run DPE verification tests against Caliptra
Browse files Browse the repository at this point in the history
Use HwModel and libcaliptra to run DPE's verification tests (written in
Go) against Caliptra.

This suite tests conformance with the DPE spec as well as related X.509
and PKCS#10 specs.
  • Loading branch information
jhand2 committed Oct 12, 2023
1 parent 0dfb4e5 commit bdd7fc8
Show file tree
Hide file tree
Showing 12 changed files with 491 additions and 50 deletions.
2 changes: 1 addition & 1 deletion dpe
Submodule dpe updated 46 files
+54 −3 .github/workflows/ci.yml
+74 −47 ci.sh
+6 −13 crypto/Cargo.lock
+2 −2 crypto/Cargo.toml
+1 −1 crypto/src/signer.rs
+47 −22 dpe/Cargo.lock
+1 −1 dpe/Cargo.toml
+21 −0 dpe/fuzz/Cargo.lock
+9 −7 dpe/src/commands/certify_key.rs
+1 −1 dpe/src/commands/derive_child.rs
+41 −34 dpe/src/commands/destroy_context.rs
+4 −5 dpe/src/commands/get_certificate_chain.rs
+1 −10 dpe/src/context.rs
+53 −23 dpe/src/x509.rs
+1 −1 platform/Cargo.toml
+2 −2 platform/src/default.rs
+ platform/src/test_data/cert_256.der
+9 −14 platform/src/test_data/cert_256.pem
+ platform/src/test_data/cert_384.der
+10 −15 platform/src/test_data/cert_384.pem
+6 −2 platform/src/test_data/generate.sh
+ platform/src/test_data/key_256.der
+3 −3 platform/src/test_data/key_256.pem
+ platform/src/test_data/key_384.der
+4 −4 platform/src/test_data/key_384.pem
+46 −21 simulator/Cargo.lock
+9 −4 simulator/Cargo.toml
+27 −12 tools/Cargo.lock
+13 −5 tools/Cargo.toml
+406 −10 verification/abi.go
+61 −98 verification/certifyKey.go
+27 −271 verification/client.go
+0 −194 verification/emulator.go
+26 −39 verification/getCertificateChain.go
+60 −0 verification/getProfile.go
+0 −282 verification/getProfile_test.go
+1 −1 verification/go.mod
+88 −0 verification/initializeContext.go
+0 −127 verification/initializeContext_test.go
+40 −0 verification/profile.go
+27 −12 verification/simulator.go
+85 −0 verification/tagTCI.go
+0 −91 verification/tagTCI_test.go
+54 −0 verification/transport.go
+44 −0 verification/verification.go
+18 −101 verification/verification_test.go
2 changes: 2 additions & 0 deletions libcaliptra/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Q=@
CC=$(CROSS_COMPILE)gcc
AR=$(CROSS_COMPILE)ar

RTL_SOC_IFC_INCLUDE_PATH ?= ../hw-latest/caliptra-rtl/src/soc_ifc/rtl

ifneq ($(MAKECMDGOALS),clean)
ifndef RTL_SOC_IFC_INCLUDE_PATH
$(error RTL_SOC_IFC_INCLUDE_PATH must be defined and point to a location where caliptra_top_reg.h can be found)
Expand Down
17 changes: 3 additions & 14 deletions libcaliptra/inc/caliptra_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,6 @@ struct caliptra_stash_measurement_resp {
uint32_t dpe_result;
};

struct caliptra_invoke_dpe_req {
struct caliptra_req_header hdr;
uint32_t data_size;
uint8_t data[512];
};

struct caliptra_invoke_dpe_resp {
struct caliptra_resp_header hdr;
uint32_t data_size;
uint8_t data[2200];
};

struct caliptra_test_get_fmc_alias_cert_resp {
struct caliptra_resp_header hdr;
uint32_t data_size;
Expand Down Expand Up @@ -211,6 +199,7 @@ struct dpe_certify_key_response {
struct dpe_resp_hdr resp_hdr;
uint8_t new_context_handle[DPE_HANDLE_SIZE];
uint8_t derived_pubkey_x[DPE_ECC_SIZE];
uint8_t derived_pubkey_y[DPE_ECC_SIZE];
uint32_t cert_size;
uint8_t cert[DPE_CERT_SIZE];
};
Expand All @@ -234,13 +223,13 @@ struct dpe_get_certificate_chain_response {
uint8_t certificate_chain[DPE_CERT_SIZE];
};

struct caliptra_dpe_req {
struct caliptra_invoke_dpe_req {
caliptra_checksum checksum;
uint32_t data_size;
uint8_t data[DPE_DATA_MAX];
};

struct caliptra_dpe_resp {
struct caliptra_invoke_dpe_resp {
struct caliptra_resp_header cpl;
uint32_t data_size;
union {
Expand Down
11 changes: 6 additions & 5 deletions runtime/src/dpe_platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
use core::cmp::min;

use arrayvec::ArrayVec;
use caliptra_drivers::cprintln;
use caliptra_drivers::{cprintln};
use crypto::Digest;
use dpe::{
x509::{Name, X509CertWriter},
x509::{DirectoryString, Name, X509CertWriter},
DPE_PROFILE,
};
use platform::{Platform, PlatformError, MAX_CHUNK_SIZE};
Expand Down Expand Up @@ -80,13 +80,14 @@ impl Platform for DpePlatform<'_> {
const CALIPTRA_CN: &[u8] = b"Caliptra Rt Alias";
let mut issuer_writer = X509CertWriter::new(out, true);

let mut serial = [0u8; DPE_PROFILE.get_hash_size() * 2];
// Caliptra RDN SerialNumber fiel is always a Sha256 hash
let mut serial = [0u8; 64];
Digest::write_hex_str(&self.hashed_rt_pub_key, &mut serial)
.map_err(|_| PlatformError::IssuerNameError)?;

let name = Name {
cn: CALIPTRA_CN,
serial,
cn: DirectoryString::Utf8String(CALIPTRA_CN),
serial: DirectoryString::PrintableString(&serial),
};
let issuer_len = issuer_writer
.encode_rdn(&name)
Expand Down
25 changes: 16 additions & 9 deletions runtime/src/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use crate::{

use arrayvec::ArrayVec;
use caliptra_drivers::{
cprintln, Array4x12, CaliptraError, CaliptraResult, DataVault, Ecc384, KeyVault, Lms,
cprintln, cprint, Array4x12, CaliptraError, CaliptraResult, DataVault, Ecc384, KeyVault, Lms,
PersistentDataAccessor, ResetReason, Sha1, SocIfc,
};
use caliptra_drivers::{Hmac384, PcrBank, PcrId, Sha256, Sha384, Sha384Acc, Trng};
use caliptra_drivers::{Hmac384, PcrBank, PcrId, Sha256, Sha256Alg, Sha384, Sha384Acc, Trng};
use caliptra_registers::mbox::enums::MboxStatusE;
use caliptra_registers::{
csrng::CsrngReg, dv::DvReg, ecc::EccReg, entropy_src::EntropySrcReg, hmac::HmacReg, kv::KvReg,
Expand All @@ -32,7 +32,7 @@ use dpe::{
DPE_PROFILE,
};

use crypto::{AlgLen, Crypto};
use crypto::{AlgLen, Crypto, CryptoBuf};

pub struct Drivers {
pub mbox: Mailbox,
Expand Down Expand Up @@ -228,21 +228,28 @@ impl Drivers {
Ok(())
}

// Caliptra Name serialNumber fields are sha256 digests
pub fn compute_rt_alias_sn(&mut self) -> CaliptraResult<CryptoBuf> {
let key = self.persistent_data.get().fht.rt_dice_pub_key.to_der();

let rt_digest = self.sha256.digest(&key)?;
let token = CryptoBuf::new(&Into::<[u8; 32]>::into(&rt_digest)).map_err(|_| CaliptraError::RUNTIME_INITIALIZE_DPE_FAILED)?;

Ok(token)
}

fn initialize_dpe(drivers: &mut Drivers) -> CaliptraResult<()> {
let locality = drivers.persistent_data.get().manifest1.header.pl0_pauser;
let rt_pub_key = drivers.persistent_data.get().fht.rt_dice_pub_key;
let hashed_rt_pub_key = drivers.compute_rt_alias_sn()?;
let mut crypto = DpeCrypto::new(
&mut drivers.sha384,
&mut drivers.trng,
&mut drivers.ecc384,
&mut drivers.hmac384,
&mut drivers.key_vault,
rt_pub_key,
drivers.persistent_data.get().fht.rt_dice_pub_key,
);
// Skip hashing first 0x04 byte of der encoding
let hashed_rt_pub_key = crypto
.hash(AlgLen::Bit384, &rt_pub_key.to_der()[1..])
.map_err(|_| CaliptraError::RUNTIME_INITIALIZE_DPE_FAILED)?;

let mut env = DpeEnv::<CptraDpeTypes> {
crypto,
platform: DpePlatform::new(locality, hashed_rt_pub_key, &mut drivers.cert_chain),
Expand Down
37 changes: 19 additions & 18 deletions runtime/src/invoke_dpe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use dpe::{
commands::{
CertifyKeyCmd, Command, CommandExecution, DeriveChildCmd, DeriveChildFlags, InitCtxCmd,
},
response::Response,
response::{Response, ResponseHdr},
DpeInstance,
};
use zerocopy::FromBytes;
Expand All @@ -26,6 +26,7 @@ impl InvokeDpeCmd {
return Err(CaliptraError::RUNTIME_MAILBOX_INVALID_PARAMS);
}

let hashed_rt_pub_key = drivers.compute_rt_alias_sn()?;
let pdata = drivers.persistent_data.get();
let rt_pub_key = pdata.fht.rt_dice_pub_key;
let mut crypto = DpeCrypto::new(
Expand All @@ -36,9 +37,6 @@ impl InvokeDpeCmd {
&mut drivers.key_vault,
rt_pub_key,
);
let hashed_rt_pub_key = crypto
.hash(AlgLen::Bit384, &rt_pub_key.to_der()[1..])
.map_err(|_| CaliptraError::RUNTIME_INITIALIZE_DPE_FAILED)?;
let image_header = &pdata.manifest1.header;
let pl0_pauser = pdata.manifest1.header.pl0_pauser;
let mut env = DpeEnv::<CptraDpeTypes> {
Expand Down Expand Up @@ -89,21 +87,24 @@ impl InvokeDpeCmd {
Command::GetCertificateChain(cmd) => cmd.execute(dpe, &mut env, locality),
};

match resp {
Ok(resp) => {
let resp_bytes = resp.as_bytes();
let data_size = resp_bytes.len();
let mut invoke_resp = InvokeDpeResp {
hdr: MailboxRespHeader::default(),
data_size: data_size as u32,
data: [0u8; InvokeDpeResp::DATA_MAX_SIZE],
};
invoke_resp.data[..data_size].copy_from_slice(resp_bytes);

Ok(MailboxResp::InvokeDpeCommand(invoke_resp))
}
_ => Err(CaliptraError::RUNTIME_INVOKE_DPE_FAILED),
}
// If DPE command failed, populate header with error code, but
// don't fail the mailbox command.
let resp_struct = match resp {
Ok(r) => r,
Err(e) => Response::Error(ResponseHdr::new(e)),
};

let resp_bytes = resp_struct.as_bytes();
let data_size = resp_bytes.len();
let mut invoke_resp = InvokeDpeResp {
hdr: MailboxRespHeader::default(),
data_size: data_size as u32,
data: [0u8; InvokeDpeResp::DATA_MAX_SIZE],
};
invoke_resp.data[..data_size].copy_from_slice(resp_bytes);

Ok(MailboxResp::InvokeDpeCommand(invoke_resp))
} else {
Err(CaliptraError::RUNTIME_INSUFFICIENT_MEMORY)
}
Expand Down
4 changes: 1 addition & 3 deletions runtime/src/stash_measurement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct StashMeasurementCmd;
impl StashMeasurementCmd {
pub(crate) fn execute(drivers: &mut Drivers, cmd_args: &[u8]) -> CaliptraResult<MailboxResp> {
if let Some(cmd) = StashMeasurementReq::read_from(cmd_args) {
let hashed_rt_pub_key = drivers.compute_rt_alias_sn()?;
let pdata = drivers.persistent_data.get();
let rt_pub_key = pdata.fht.rt_dice_pub_key;
let mut crypto = DpeCrypto::new(
Expand All @@ -28,9 +29,6 @@ impl StashMeasurementCmd {
&mut drivers.key_vault,
rt_pub_key,
);
let hashed_rt_pub_key = crypto
.hash(AlgLen::Bit384, &rt_pub_key.to_der()[1..])
.map_err(|_| CaliptraError::RUNTIME_INITIALIZE_DPE_FAILED)?;
let mut env = DpeEnv::<CptraDpeTypes> {
crypto,
platform: DpePlatform::new(
Expand Down
29 changes: 29 additions & 0 deletions test/dpe_verification/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
LIBCALIPTRA_DIR = ../../libcaliptra
HW_MODEL_C_DIR = ../../hw-model/c-binding
TARGET_DIR = ../../target
BUILDER_DIR = ../../builder

ROM_FILE = /tmp/caliptra_rom.bin
FW_FILE = /tmp/image_bundle.bin

LIBCALIPTRA = $(LIBCALIPTRA_DIR)/libcaliptra.a
LIB_HW_MODEL = $(TARGET_DIR)/debug/libcaliptra_hw_model_c_binding.a

EXTRA_CARGO_CONFIG = target.'cfg(all())'.rustflags = [\"-Dwarnings\"]

.PHONY: $(LIBCALIPTRA) $(LIB_HW_MODEL) $(ROM_FILE) $(FW_FILE)

$(LIBCALIPTRA):
# For some reason, libcaliptra doesn't get rebuilt when the code changes.
# That will need to be fixed in the libcaliptra Makefile.
make -C $(LIBCALIPTRA_DIR) clean
make -C $(LIBCALIPTRA_DIR)

$(LIB_HW_MODEL):
cargo build --config="$(EXTRA_CARGO_CONFIG)" --manifest-path $(HW_MODEL_C_DIR)/Cargo.toml

$(FW_FILE) $(ROM_FILE):
cargo --config="$(EXTRA_CARGO_CONFIG)" run --manifest-path=$(BUILDER_DIR)/Cargo.toml --bin image -- --fw $(FW_FILE) --rom-no-log=$(ROM_FILE)

run: $(LIBCALIPTRA) $(LIB_HW_MODEL) $(FW_FILE) $(ROM_FILE)
ROM_PATH=$(ROM_FILE) FW_PATH=$(FW_FILE) go test -v
26 changes: 26 additions & 0 deletions test/dpe_verification/dpe_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package dpe

import (
"github.com/chipsalliance/caliptra-dpe/verification"
"os"
"testing"
)

func TestRunAll(t *testing.T) {
for _, test := range verification.TestCases {
t.Run(test.Name, func(t *testing.T) {
var d verification.TestDPEInstance = &CptraModel{exe_path: ""}

if !verification.HasSupportNeeded(d, test.SupportNeeded) {
t.Skipf("Warning: Target does not have required support, skipping test.")
}

test.Run(d, t)
})
}
}

func TestMain(m *testing.M) {
exitVal := m.Run()
os.Exit(exitVal)
}
18 changes: 18 additions & 0 deletions test/dpe_verification/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module dpe

go 1.22

replace github.com/chipsalliance/caliptra-dpe/verification => ../../dpe/verification

require github.com/chipsalliance/caliptra-dpe/verification v0.0.0-20231002193428-bb19016edf87

require (
github.com/pelletier/go-toml v1.9.3 // indirect
github.com/weppos/publicsuffix-go v0.30.1-0.20230422193905-8fecedd899db // indirect
github.com/zmap/zcrypto v0.0.0-20230422215203-9a665e1e9968 // indirect
github.com/zmap/zlint/v3 v3.4.1 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/text v0.8.0 // indirect
)
Loading

0 comments on commit bdd7fc8

Please sign in to comment.