From bce021badf331641dce5cfe7b69f69677cf43ffc Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Wed, 21 Aug 2024 18:20:16 -0700 Subject: [PATCH] [personalization] add Dev Seed hash to the set of perso TLV objects The dev seed hash object is an array of two 64 byte variables, which are 16th generation HMAC KDF of the entropy produced on the device. The new object is passed in a perso TLV blob along with the certificates generated on the device. The object contents are hashed in the same hash stream where certificates' contents are hashed, the resulting hash is compared by the host with the locally produced hash. The Cros personalization end to end test succeeds, the Dev seed hash is printed out in the test log. Signed-off-by: Vadim Bendebury --- sw/device/silicon_creator/manuf/base/BUILD | 1 + .../manuf/base/ft_personalize.c | 23 +++++++------ .../manuf/base/perso_tlv_data.h | 13 ++++++++ .../manuf/extensions/BUILD.bazel | 2 ++ .../manuf/lib/flash_info_fields.c | 7 ++++ .../manuf/lib/flash_info_fields.h | 2 ++ sw/host/provisioning/ft_lib/src/lib.rs | 32 ++++++++++++++++--- sw/host/provisioning/perso_tlv_lib/src/lib.rs | 4 +-- 8 files changed, 68 insertions(+), 16 deletions(-) diff --git a/sw/device/silicon_creator/manuf/base/BUILD b/sw/device/silicon_creator/manuf/base/BUILD index 04abb49a9f9078..376297a99ee48c 100644 --- a/sw/device/silicon_creator/manuf/base/BUILD +++ b/sw/device/silicon_creator/manuf/base/BUILD @@ -270,6 +270,7 @@ cc_library( "//sw/device/silicon_creator/lib/drivers:flash_ctrl", "//sw/device/silicon_creator/lib/drivers:hmac", "//sw/device/silicon_creator/manuf/base:perso_tlv_data", + "//sw/device/silicon_creator/manuf/lib:flash_info_fields", "//sw/device/silicon_creator/manuf/lib:personalize", ], ) diff --git a/sw/device/silicon_creator/manuf/base/ft_personalize.c b/sw/device/silicon_creator/manuf/base/ft_personalize.c index 194df10b97c7f2..c5b8a4813592cd 100644 --- a/sw/device/silicon_creator/manuf/base/ft_personalize.c +++ b/sw/device/silicon_creator/manuf/base/ft_personalize.c @@ -291,7 +291,6 @@ static status_t hash_certificate(const flash_ctrl_info_page_t *page, static status_t log_hash_of_all_certs(ujson_t *uj) { uint32_t cert_size; - serdes_sha256_hash_t hash; hmac_sha256_init(); // Push all certificates into the hash. @@ -309,14 +308,6 @@ static status_t log_hash_of_all_certs(ujson_t *uj) { } } - // Log the final hash of all certificates to the host and console. - hmac_sha256_process(); - hmac_sha256_final((hmac_digest_t *)&hash); - RESP_OK(ujson_serialize_serdes_sha256_hash_t, uj, &hash); - LOG_INFO("SHA256 hash of all certificates: %08x%08x%08x%08x%08x%08x%08x%08x", - hash.data[7], hash.data[6], hash.data[5], hash.data[4], hash.data[3], - hash.data[2], hash.data[1], hash.data[0]); - return OK_STATUS(); } @@ -589,6 +580,10 @@ static status_t personalize_endorse_certificates(ujson_t *uj) { return OK_STATUS(); } +static status_t send_final_hash(ujson_t *uj, serdes_sha256_hash_t *hash) { + return RESP_OK(ujson_serialize_serdes_sha256_hash_t, uj, hash); +} + bool test_main(void) { CHECK_STATUS_OK(peripheral_handles_init()); ujson_t uj = ujson_ottf_console(); @@ -606,6 +601,7 @@ bool test_main(void) { CHECK_STATUS_OK(personalize_extension_pre_cert_endorse(&pre_endorse)); CHECK_STATUS_OK(personalize_endorse_certificates(&uj)); + CHECK_STATUS_OK(log_hash_of_all_certs(&uj)); personalize_extension_post_endorse_t post_endorse = { .uj = &uj, @@ -613,7 +609,14 @@ bool test_main(void) { .cert_flash_layout = cert_flash_layout}; CHECK_STATUS_OK(personalize_extension_post_cert_endorse(&post_endorse)); - CHECK_STATUS_OK(log_hash_of_all_certs(&uj)); + // Log the final hash of all certificates to the host and console. + serdes_sha256_hash_t hash; + hmac_sha256_process(); + hmac_sha256_final((hmac_digest_t *)&hash); + CHECK_STATUS_OK(send_final_hash(&uj, &hash)); + LOG_INFO("SHA256 hash of all certificates: %08x%08x%08x%08x%08x%08x%08x%08x", + hash.data[7], hash.data[6], hash.data[5], hash.data[4], hash.data[3], + hash.data[2], hash.data[1], hash.data[0]); // DO NOT CHANGE THE BELOW STRING without modifying the host code in // sw/host/provisioning/ft_lib/src/lib.rs diff --git a/sw/device/silicon_creator/manuf/base/perso_tlv_data.h b/sw/device/silicon_creator/manuf/base/perso_tlv_data.h index d2b3241870f33d..7f523b5404c859 100644 --- a/sw/device/silicon_creator/manuf/base/perso_tlv_data.h +++ b/sw/device/silicon_creator/manuf/base/perso_tlv_data.h @@ -47,6 +47,19 @@ typedef enum perso_tlv_obj_header_fields { kObjhTypeFieldMask = (1 << kObjhTypeFieldWidth) - 1, } perso_tlv_obj_header_fields_t; +typedef struct perso_tlv_dev_seed_element { + uint32_t el[8]; +} perso_tlv_dev_seed_element_t; + +typedef struct perso_tlv_dev_seed { + perso_tlv_dev_seed_element_t key; + perso_tlv_dev_seed_element_t context; +} perso_tlv_dev_seed_t; + +typedef struct perso_tlv_dev_seed_set { + perso_tlv_dev_seed_t seeds[2]; +} perso_tlv_dev_seed_set_t; + /** * The x509 certificate is prepended by a 16 bits header followed by the ASCII * characters of the certificate name, followed by the certificate body. diff --git a/sw/device/silicon_creator/manuf/extensions/BUILD.bazel b/sw/device/silicon_creator/manuf/extensions/BUILD.bazel index d0c60c13a12087..08c4c93bd7b399 100644 --- a/sw/device/silicon_creator/manuf/extensions/BUILD.bazel +++ b/sw/device/silicon_creator/manuf/extensions/BUILD.bazel @@ -30,6 +30,7 @@ cc_library( "@//sw/device/lib/testing/test_framework:ujson_ottf", "@//sw/device/silicon_creator/lib/cert", "@//sw/device/silicon_creator/manuf/base:personalize_ext", + "@//sw/device/silicon_creator/manuf/lib:flash_info_fields", ], ) @@ -43,6 +44,7 @@ cc_library( "@//sw/device/lib/testing/test_framework:ujson_ottf", "@//sw/device/silicon_creator/lib/cert", "@//sw/device/silicon_creator/manuf/base:personalize_ext", + "@//sw/device/silicon_creator/manuf/lib:flash_info_fields", ], ) diff --git a/sw/device/silicon_creator/manuf/lib/flash_info_fields.c b/sw/device/silicon_creator/manuf/lib/flash_info_fields.c index e8408d1c02211b..5d0a9fbec8d889 100644 --- a/sw/device/silicon_creator/manuf/lib/flash_info_fields.c +++ b/sw/device/silicon_creator/manuf/lib/flash_info_fields.c @@ -104,6 +104,13 @@ const flash_info_field_t kFlashInfoFieldTpmCikAttestationKeySeed = { .byte_offset = kFlashInfoFieldTpmCikKeySeedIdx * kAttestationSeedBytes, }; +const flash_info_field_t kFlashInfoFieldDevSeedSeed = { + .partition = 0, + .bank = 0, + .page = 4, + .byte_offset = kFlashInfoFieldDevSeedSeedIdx * kAttestationSeedBytes, +}; + const flash_info_field_t kFlashInfoFieldAttestationKeyGenVersion = { .partition = 0, .bank = 0, diff --git a/sw/device/silicon_creator/manuf/lib/flash_info_fields.h b/sw/device/silicon_creator/manuf/lib/flash_info_fields.h index c7af39f681cffa..981d4a171ea4f5 100644 --- a/sw/device/silicon_creator/manuf/lib/flash_info_fields.h +++ b/sw/device/silicon_creator/manuf/lib/flash_info_fields.h @@ -41,6 +41,7 @@ enum { kFlashInfoFieldTpmEkKeySeedIdx = 3, kFlashInfoFieldTpmCekKeySeedIdx = 4, kFlashInfoFieldTpmCikKeySeedIdx = 5, + kFlashInfoFieldDevSeedSeedIdx = 6, }; extern const flash_info_field_t kFlashInfoFieldDeviceId; @@ -55,6 +56,7 @@ extern const flash_info_field_t kFlashInfoFieldCdi1AttestationKeySeed; extern const flash_info_field_t kFlashInfoFieldTpmEkAttestationKeySeed; extern const flash_info_field_t kFlashInfoFieldTpmCekAttestationKeySeed; extern const flash_info_field_t kFlashInfoFieldTpmCikAttestationKeySeed; +extern const flash_info_field_t kFlashInfoFieldDevSeedSeed; extern const flash_info_field_t kFlashInfoFieldAttestationKeyGenVersion; /** diff --git a/sw/host/provisioning/ft_lib/src/lib.rs b/sw/host/provisioning/ft_lib/src/lib.rs index 87c7c5c0547832..1a90f34e60fbb6 100644 --- a/sw/host/provisioning/ft_lib/src/lib.rs +++ b/sw/host/provisioning/ft_lib/src/lib.rs @@ -279,6 +279,22 @@ fn push_endorsed_cert( Ok(()) } +fn process_dev_seeds(seeds: &[u8]) -> Result<()> { + let expected_seed_num = 2usize; + let seed_size = 64usize; + + if seeds.len() != seed_size * expected_seed_num { + bail!("Unexpected seeds perso object size {}", seeds.len()) + } + + for i in 0..expected_seed_num { + let seed = &seeds[i * seed_size..(i + 1) * seed_size]; + + log::info!("Seed #{}: {}", i, hex::encode(seed)) + } + Ok(()) +} + fn provision_certificates( transport: &TransportWrapper, cert_endorsement_key_wrapper: KeyWrapper, @@ -308,8 +324,6 @@ fn provision_certificates( } }; - log::info!("start of the body {}", hex::encode(&perso_blob.body[0..10])); - // Extract certificate byte vectors, endorse TBS certs, and ensure they parse with OpenSSL. // During the process, both: // 1. prepare a UJSON payload of endorsed certs to send back to the device, @@ -324,14 +338,24 @@ fn provision_certificates( for _ in 0..perso_blob.num_objs { log::info!("Processing next object"); let header = get_obj_header(&perso_blob.body[start..])?; + let obj_header_size = std::mem::size_of::(); + + if header.obj_size > (perso_blob.body.len() - start) { + bail!("Perso blob overflow!"); + } + start += obj_header_size; match header.obj_type { ObjType::EndorsedX509Cert | ObjType::UnendorsedX509Cert => (), ObjType::DevSeed => { - start += header.obj_size; + let dev_seed_size = header.obj_size - obj_header_size; + log::info!("obj size {}, seed size {}", header.obj_size, dev_seed_size); + let seeds = &perso_blob.body[start..start + dev_seed_size]; + cert_hasher.update(seeds); + process_dev_seeds(seeds)?; + start += dev_seed_size; continue; } } - start += std::mem::size_of::(); // The next object is a cert, let's retrieve its properties (name, needs // endorsement, etc.) diff --git a/sw/host/provisioning/perso_tlv_lib/src/lib.rs b/sw/host/provisioning/perso_tlv_lib/src/lib.rs index 181acc2c927ef3..4dabfb028fb22e 100644 --- a/sw/host/provisioning/perso_tlv_lib/src/lib.rs +++ b/sw/host/provisioning/perso_tlv_lib/src/lib.rs @@ -6,7 +6,7 @@ use anyhow::{bail, Result}; // Types of objects which can come from the device in the perso blob. #[repr(C)] -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] 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, @@ -18,7 +18,7 @@ impl ObjType { match value { 0 => Ok(ObjType::UnendorsedX509Cert), 1 => Ok(ObjType::EndorsedX509Cert), - 3 => Ok(ObjType::DevSeed), + 2 => Ok(ObjType::DevSeed), _ => bail!("incorrect input value of {value} for ObjType"), } }