Skip to content

Commit

Permalink
[dice,cwt] Endorse and store all 4 DICE CWT certificates
Browse files Browse the repository at this point in the history
Signed-off-by: Tommy Chiu <[email protected]>
  • Loading branch information
tommychiu-github committed Nov 1, 2024
1 parent 53e532e commit b26205b
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 16 deletions.
1 change: 1 addition & 0 deletions sw/device/silicon_creator/lib/cert/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ cc_library(
"//sw/device/silicon_creator/lib:attestation",
"//sw/device/silicon_creator/lib:otbn_boot_services",
"//sw/device/silicon_creator/lib/base:util",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/manuf/lib:flash_info_fields",
],
)
Expand Down
28 changes: 25 additions & 3 deletions sw/device/silicon_creator/manuf/base/ft_personalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static cert_key_id_pair_t cdi_1_key_ids = {
.cert = &cdi_1_pubkey_id,
};
static ecdsa_p256_public_key_t curr_pubkey = {.x = {0}, .y = {0}};
static ecdsa_p256_public_key_t uds_pubkey = {.x = {0}, .y = {0}};
static perso_blob_t perso_blob_to_host; // Perso data device => host.
static perso_blob_t perso_blob_from_host; // Perso data host => device.

Expand Down Expand Up @@ -364,6 +365,7 @@ static status_t hash_certificate(const flash_ctrl_info_page_t *page,
if (size) {
*size = obj_size;
}

return OK_STATUS();
}

Expand Down Expand Up @@ -445,6 +447,7 @@ static status_t personalize_gen_dice_certificates(ujson_t *uj) {
curr_cert_size = kUdsMaxTbsSizeBytes;
TRY(otbn_boot_cert_ecc_p256_keygen(kDiceKeyUds, &uds_pubkey_id,
&curr_pubkey));
memcpy(&uds_pubkey, &curr_pubkey, sizeof(ecdsa_p256_public_key_t));
TRY(otbn_boot_attestation_key_save(kDiceKeyUds.keygen_seed_idx,
kDiceKeyUds.type,
*kDiceKeyUds.keymgr_diversifier));
Expand All @@ -455,7 +458,13 @@ static status_t personalize_gen_dice_certificates(ujson_t *uj) {
&otp_rot_creator_auth_codesign_measurement,
&otp_rot_creator_auth_state_measurement, &uds_key_ids, &curr_pubkey,
all_certs, &curr_cert_size));
TRY(perso_tlv_prepare_cert_for_shipping("UDS", true, all_certs,

bool needs_endorsement;
if (all_certs[0] == 0x30 || all_certs[1] == 0x82)
needs_endorsement = true;
else
needs_endorsement = false;
TRY(perso_tlv_prepare_cert_for_shipping("UDS", needs_endorsement, all_certs,
curr_cert_size, &perso_blob_to_host));

// Generate CDI_0 keys and cert.
Expand Down Expand Up @@ -591,11 +600,17 @@ static status_t personalize_endorse_certificates(ujson_t *uj) {
// Helper structure caching certificate information.
perso_tlv_cert_block_t block;
// UDS cert.
// FIXME: NOT pixel
#if 0
TRY(extract_next_cert(&next_cert, &free_room));

// Now the two CDI certs which were endorsed locally and sent to the host
// earlier.
size_t cdis[] = {cdi_0_offset, cdi_1_offset};
#else
size_t cdis[] = {0, cdi_0_offset, cdi_1_offset};
#endif

for (size_t i = 0; i < ARRAYSIZE(cdis); i++) {
size_t offset = cdis[i];
TRY(perso_tlv_set_cert_block(perso_blob_to_host.body + offset,
Expand All @@ -609,7 +624,6 @@ static status_t personalize_endorse_certificates(ujson_t *uj) {
next_cert += block.obj_size;
free_room -= block.obj_size;
}

// Now the rest of endorsed certificates received from the host, if any.
while (perso_blob_from_host.num_objs)
TRY(extract_next_cert(&next_cert, &free_room));
Expand Down Expand Up @@ -733,7 +747,15 @@ bool test_main(void) {
.certgen_inputs = &certgen_inputs,
.perso_blob_to_host = &perso_blob_to_host,
.cert_flash_layout = cert_flash_layout,
.flash_ctrl_handle = &flash_ctrl_state};
.flash_ctrl_handle = &flash_ctrl_state,
.uds_pubkey = &uds_pubkey,
.uds_pubkey_id = &uds_pubkey_id,
.otp_creator_sw_cfg_measurement = &otp_creator_sw_cfg_measurement,
.otp_owner_sw_cfg_measurement = &otp_owner_sw_cfg_measurement,
.otp_rot_creator_auth_codesign_measurement =
&otp_rot_creator_auth_codesign_measurement,
.otp_rot_creator_auth_state_measurement =
&otp_rot_creator_auth_state_measurement};
CHECK_STATUS_OK(personalize_extension_pre_cert_endorse(&pre_endorse));

CHECK_STATUS_OK(personalize_endorse_certificates(&uj));
Expand Down
7 changes: 5 additions & 2 deletions sw/device/silicon_creator/manuf/base/perso_tlv_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ status_t perso_tlv_set_cert_block(const uint8_t *buf, size_t max_room,
block->obj_size = obj_size;

PERSO_TLV_GET_FIELD(Objh, Type, objh, &obj_type);
if (obj_type != kPersoObjectTypeX509Cert) {
if (obj_type != kPersoObjectTypeX509Cert &&
obj_type != kPersoObjectTypeCwtCert) {
LOG_INFO("Skipping object of type %d", obj_type);
return NOT_FOUND();
}
Expand Down Expand Up @@ -116,7 +117,9 @@ status_t perso_tlv_prepare_cert_for_shipping(const char *name,
if (needs_endorsement) {
PERSO_TLV_SET_FIELD(Objh, Type, obj_header, kPersoObjectTypeX509Tbs);
} else {
PERSO_TLV_SET_FIELD(Objh, Type, obj_header, kPersoObjectTypeX509Cert);
// TODO(lowRISC/opentitan:#24281): should decide the obj_type by other
// factor
PERSO_TLV_SET_FIELD(Objh, Type, obj_header, kPersoObjectTypeCwtCert);
}

PERSO_TLV_SET_FIELD(Objh, Size, obj_header, obj_len);
Expand Down
1 change: 1 addition & 0 deletions sw/device/silicon_creator/manuf/base/perso_tlv_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ typedef enum perso_tlv_object_type {
kPersoObjectTypeX509Tbs = 0,
kPersoObjectTypeX509Cert = 1,
kPersoObjectTypeDevSeed = 2,
kPersoObjectTypeCwtCert = 3,
} perso_tlv_object_type_t;

typedef uint16_t perso_tlv_object_header_t;
Expand Down
14 changes: 14 additions & 0 deletions sw/device/silicon_creator/manuf/base/personalize_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ typedef struct personalize_extension_pre_endorse {
* Pointer to the flash controller handle necessary for proper flash access.
*/
dif_flash_ctrl_state_t *flash_ctrl_handle;

/**
* Pointer to the UDS public key necessary for the following perso extension.
*/
ecdsa_p256_public_key_t *uds_pubkey;
hmac_digest_t *uds_pubkey_id;

/**
* Pointer to the OTP measurements necessary for the following perso extension.
*/
hmac_digest_t *otp_creator_sw_cfg_measurement;
hmac_digest_t *otp_owner_sw_cfg_measurement;
hmac_digest_t *otp_rot_creator_auth_codesign_measurement;
hmac_digest_t *otp_rot_creator_auth_state_measurement;
} personalize_extension_pre_endorse_t;

/**
Expand Down
18 changes: 7 additions & 11 deletions sw/host/provisioning/ft_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,6 @@ fn get_cert(data: &[u8]) -> Result<CertHeader> {
let header_size = header_len + name_len;
let cert_body: Vec<u8> = data[header_size..wrapped_size].to_vec();

// Sanity check, total size and cert size must match
let cert_size = get_cert_size(&cert_body)?;
if cert_size != cert_body.len() {
bail!(
"cert size {} does not match length {}",
cert_size,
cert_body.len()
);
}
Ok(CertHeader {
wrapped_size,
cert_name,
Expand Down Expand Up @@ -343,7 +334,9 @@ fn provision_certificates(
}
start += obj_header_size;
match header.obj_type {
ObjType::EndorsedX509Cert | ObjType::UnendorsedX509Cert => (),
ObjType::EndorsedX509Cert | ObjType::UnendorsedX509Cert | ObjType::EndorsedCwtCert => {
()
}
ObjType::DevSeed => {
let dev_seed_size = header.obj_size - obj_header_size;
let seeds = &perso_blob.body[start..start + dev_seed_size];
Expand Down Expand Up @@ -380,7 +373,10 @@ fn provision_certificates(
};
// Ensure all certs parse with OpenSSL (even those that where endorsed on device).
log::info!("{} Cert: {}", cert.cert_name, hex::encode(&cert_bytes));
let _ = parse_certificate(&cert_bytes)?;
// TODO(lowRISC/opentitan:#24281): Add CWT parser
if header.obj_type != ObjType::DevSeed && header.obj_type != ObjType::EndorsedCwtCert {
let _ = parse_certificate(&cert_bytes)?;
}
// Push the cert into the hasher so we can ensure the certs written to the device's flash
// info pages match those verified on the host.
cert_hasher.update(cert_bytes);
Expand Down
2 changes: 2 additions & 0 deletions sw/host/provisioning/perso_tlv_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub enum ObjType {
UnendorsedX509Cert = perso_tlv_objects::perso_tlv_object_type_kPersoObjectTypeX509Tbs as isize,
EndorsedX509Cert = perso_tlv_objects::perso_tlv_object_type_kPersoObjectTypeX509Cert as isize,
DevSeed = perso_tlv_objects::perso_tlv_object_type_kPersoObjectTypeDevSeed as isize,
EndorsedCwtCert = perso_tlv_objects::perso_tlv_object_type_kPersoObjectTypeCwtCert as isize,
}

impl ObjType {
Expand All @@ -19,6 +20,7 @@ impl ObjType {
0 => Ok(ObjType::UnendorsedX509Cert),
1 => Ok(ObjType::EndorsedX509Cert),
2 => Ok(ObjType::DevSeed),
3 => Ok(ObjType::EndorsedCwtCert),
_ => bail!("incorrect input value of {value} for ObjType"),
}
}
Expand Down

0 comments on commit b26205b

Please sign in to comment.