From 32c42ca99db21abd0e2482ae1e681a0dac2616e0 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 | 25 ++++++++------- .../manuf/base/perso_tlv_data.h | 13 ++++++++ .../manuf/extensions/BUILD.bazel | 2 ++ .../manuf/lib/flash_info_fields.c | 14 --------- .../manuf/lib/flash_info_fields.h | 3 +- sw/host/provisioning/ft_lib/src/lib.rs | 31 ++++++++++++++++--- sw/host/provisioning/perso_tlv_lib/src/lib.rs | 4 +-- 8 files changed, 60 insertions(+), 33 deletions(-) diff --git a/sw/device/silicon_creator/manuf/base/BUILD b/sw/device/silicon_creator/manuf/base/BUILD index 281419f5f13a8..98a55fda0a701 100644 --- a/sw/device/silicon_creator/manuf/base/BUILD +++ b/sw/device/silicon_creator/manuf/base/BUILD @@ -271,6 +271,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 9f11df7e17ecb..384ba1a331511 100644 --- a/sw/device/silicon_creator/manuf/base/ft_personalize.c +++ b/sw/device/silicon_creator/manuf/base/ft_personalize.c @@ -289,9 +289,8 @@ static status_t hash_certificate(const flash_ctrl_info_page_t *page, return OK_STATUS(); } -static status_t log_hash_of_all_certs(ujson_t *uj) { +static status_t hash_all_certs(void) { 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(); } @@ -592,6 +583,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(); @@ -609,6 +604,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(hash_all_certs()); personalize_extension_post_endorse_t post_endorse = { .uj = &uj, @@ -616,7 +612,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 hash of all perso objects 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 perso objects: %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 d2b3241870f33..7f523b5404c85 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 d0c60c13a1208..08c4c93bd7b39 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 1dea6497e606c..1e3ae477c0341 100644 --- a/sw/device/silicon_creator/manuf/lib/flash_info_fields.c +++ b/sw/device/silicon_creator/manuf/lib/flash_info_fields.c @@ -99,20 +99,6 @@ const flash_info_field_t kFlashInfoFieldTpmEkAttestationKeySeed = { .byte_offset = kFlashInfoFieldTpmEkKeySeedIdx * kAttestationSeedBytes, }; -const flash_info_field_t kFlashInfoFieldTpmCekAttestationKeySeed = { - .partition = 0, - .bank = 0, - .page = 4, - .byte_offset = kFlashInfoFieldTpmCekKeySeedIdx * kAttestationSeedBytes, -}; - -const flash_info_field_t kFlashInfoFieldTpmCikAttestationKeySeed = { - .partition = 0, - .bank = 0, - .page = 4, - .byte_offset = kFlashInfoFieldTpmCikKeySeedIdx * 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 f26969c53fe27..affb37f6dcbd9 100644 --- a/sw/device/silicon_creator/manuf/lib/flash_info_fields.h +++ b/sw/device/silicon_creator/manuf/lib/flash_info_fields.h @@ -41,8 +41,6 @@ enum { kFlashInfoFieldCdi0KeySeedIdx = 1, kFlashInfoFieldCdi1KeySeedIdx = 2, kFlashInfoFieldTpmEkKeySeedIdx = 3, - kFlashInfoFieldTpmCekKeySeedIdx = 4, - kFlashInfoFieldTpmCikKeySeedIdx = 5, }; extern const flash_info_field_t kFlashInfoFieldDeviceId; @@ -58,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 c9742df9ef4c0..d834d67aa3832 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,23 @@ 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; + 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 181acc2c927ef..4dabfb028fb22 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"), } }