9 #include "sw/device/lib/crypto/drivers/entropy.h"
15 #include "sw/device/lib/testing/json/provisioning_data.h"
16 #include "sw/device/lib/testing/lc_ctrl_testutils.h"
17 #include "sw/device/lib/testing/rstmgr_testutils.h"
18 #include "sw/device/lib/testing/test_framework/check.h"
20 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
21 #include "sw/device/lib/testing/test_framework/status.h"
22 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
23 #include "sw/device/silicon_creator/lib/attestation.h"
24 #include "sw/device/silicon_creator/lib/base/boot_measurements.h"
26 #include "sw/device/silicon_creator/lib/base/util.h"
27 #include "sw/device/silicon_creator/lib/cert/cdi_0.h"
28 #include "sw/device/silicon_creator/lib/cert/cdi_1.h"
29 #include "sw/device/silicon_creator/lib/cert/cert.h"
30 #include "sw/device/silicon_creator/lib/cert/dice.h"
31 #include "sw/device/silicon_creator/lib/cert/uds.h"
32 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
33 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
34 #include "sw/device/silicon_creator/lib/drivers/keymgr.h"
35 #include "sw/device/silicon_creator/lib/drivers/kmac.h"
36 #include "sw/device/silicon_creator/lib/drivers/otp.h"
37 #include "sw/device/silicon_creator/lib/error.h"
38 #include "sw/device/silicon_creator/lib/manifest.h"
39 #include "sw/device/silicon_creator/lib/otbn_boot_services.h"
40 #include "sw/device/silicon_creator/manuf/base/perso_tlv_data.h"
41 #include "sw/device/silicon_creator/manuf/base/personalize_ext.h"
42 #include "sw/device/silicon_creator/manuf/lib/flash_info_fields.h"
43 #include "sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h"
44 #include "sw/device/silicon_creator/manuf/lib/personalize.h"
46 #include "flash_ctrl_regs.h"
49 OTTF_DEFINE_TEST_CONFIG(.console.type = kOttfConsoleSpiDevice,
51 .console.test_may_clobber =
false, );
57 kDiceMeasuredOtpPartitionMaxSizeIn32bitWords =
58 (OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE -
59 OTP_CTRL_PARAM_OWNER_SW_CFG_DIGEST_SIZE) /
63 static uint32_t otp_state[kDiceMeasuredOtpPartitionMaxSizeIn32bitWords] = {0};
67 OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE > OTP_CTRL_PARAM_CREATOR_SW_CFG_SIZE &&
68 OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE > OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE &&
69 OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE > OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE,
70 "The largest DICE measured OTP partition is no longer the "
71 "OwnerSwCfg partition. Update the "
72 "kDiceMeasuredOtpPartitionMaxSizeIn32bitWords constant.");
79 static dif_lc_ctrl_t lc_ctrl;
80 static dif_otp_ctrl_t otp_ctrl;
81 static dif_rstmgr_t rstmgr;
94 static hmac_digest_t otp_rot_creator_auth_codesign_measurement;
96 static manuf_certgen_inputs_t certgen_inputs;
103 .cert = &uds_pubkey_id,
107 .cert = &cdi_0_pubkey_id,
111 .cert = &cdi_1_pubkey_id,
115 static perso_blob_t perso_blob_to_host;
116 static perso_blob_t perso_blob_from_host;
121 static uint8_t all_certs[8192];
123 enum { kBufferSize = 1024 };
124 static alignas(uint32_t) uint8_t cert_buffer[kBufferSize];
125 static size_t uds_offset;
126 static size_t cdi_0_offset;
127 static size_t cdi_1_offset;
134 .group_name =
"FACTORY",
135 .info_page = &kFlashCtrlInfoPageFactoryCerts,
140 .group_name =
"DICE",
141 .info_page = &kFlashCtrlInfoPageDiceCerts,
148 .group_name =
"Ext0",
149 .info_page = &kFlashCtrlInfoPageOwnerReserved6,
154 .group_name =
"Ext1",
155 .info_page = &kFlashCtrlInfoPageOwnerReserved7,
160 static void log_self_hash(
void) {
162 LOG_INFO(
"Personalization Firmware Hash: 0x%08x%08x%08x%08x%08x%08x%08x%08x",
177 static const manifest_t *rom_ext_manifest_b_get(
void) {
182 extern const uint32_t kCreatorSwCfgManufStateValue;
187 static status_t check_next_slot_bootable(
void) {
195 static status_t peripheral_handles_init(
void) {
199 TRY(dif_lc_ctrl_init(
201 TRY(dif_otp_ctrl_init(
211 static void sw_reset(
void) {
212 rstmgr_testutils_reason_clear();
220 static status_t config_and_erase_certificate_flash_pages(
void) {
221 flash_ctrl_cert_info_page_creator_cfg(&kFlashCtrlInfoPageAttestationKeySeeds);
222 flash_ctrl_cert_info_page_creator_cfg(&kFlashCtrlInfoPageFactoryCerts);
223 flash_ctrl_cert_info_page_creator_cfg(&kFlashCtrlInfoPageDiceCerts);
226 TRY(flash_ctrl_info_erase(&kFlashCtrlInfoPageFactoryCerts,
227 kFlashCtrlEraseTypePage));
228 TRY(flash_ctrl_info_erase(&kFlashCtrlInfoPageDiceCerts,
229 kFlashCtrlEraseTypePage));
237 static status_t measure_otp_partition(otp_partition_t partition,
239 bool use_expected_values) {
241 otp_dai_read(partition, 0, otp_state,
242 kOtpPartitions[partition].size /
sizeof(uint32_t));
244 if (use_expected_values) {
247 if (partition == kOtpPartitionOwnerSwCfg) {
248 manuf_individualize_device_partition_expected_read(
250 }
else if (partition == kOtpPartitionCreatorSwCfg) {
251 manuf_individualize_device_partition_expected_read(
256 hmac_sha256(otp_state, kOtpPartitions[partition].size, measurement);
268 if (!status_ok(manuf_personalize_device_secret1_check(&otp_ctrl))) {
269 TRY(manuf_personalize_device_secret1(&lc_ctrl, &otp_ctrl));
272 manuf_individualize_device_flash_data_default_cfg_check(&otp_ctrl))) {
273 TRY(manuf_individualize_device_field_cfg(
275 OTP_CTRL_PARAM_CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG_OFFSET));
282 if (!status_ok(manuf_personalize_device_secrets_check(&otp_ctrl))) {
283 lc_token_hash_t token_hash;
286 LOG_INFO(
"Waiting For RMA Unlock Token Hash ...");
288 UJSON_WITH_CRC(ujson_deserialize_lc_token_hash_t, uj, &token_hash));
290 TRY(manuf_personalize_device_secrets(&flash_ctrl_state, &lc_ctrl, &otp_ctrl,
292 TRY(manuf_personalize_flash_asymm_key_seed(
293 &flash_ctrl_state, kFlashInfoFieldUdsAttestationKeySeed,
294 kAttestationSeedWords));
295 TRY(manuf_personalize_flash_asymm_key_seed(
296 &flash_ctrl_state, kFlashInfoFieldCdi0AttestationKeySeed,
297 kAttestationSeedWords));
298 TRY(manuf_personalize_flash_asymm_key_seed(
299 &flash_ctrl_state, kFlashInfoFieldCdi1AttestationKeySeed,
300 kAttestationSeedWords));
303 uint32_t kKeyGenVersion = kAttestationKeyGenVersion0;
304 TRY(manuf_flash_info_field_write(
305 &flash_ctrl_state, kFlashInfoFieldAttestationKeyGenVersion,
321 static void compute_keymgr_owner_int_binding(manuf_certgen_inputs_t *inputs) {
322 memcpy(attestation_binding_value.data, inputs->rom_ext_measurement,
323 kDiceMeasurementSizeInBytes);
324 memset(sealing_binding_value.data, 0, kDiceMeasurementSizeInBytes);
333 static void compute_keymgr_owner_binding(manuf_certgen_inputs_t *inputs) {
336 hmac_sha256_update((
unsigned char *)inputs->owner_measurement,
337 kDiceMeasurementSizeInBytes);
338 hmac_sha256_update((
unsigned char *)inputs->owner_manifest_measurement,
339 kDiceMeasurementSizeInBytes);
340 hmac_sha256_process();
341 hmac_sha256_final(&combined_measurements);
342 memcpy(attestation_binding_value.data, combined_measurements.digest,
343 kDiceMeasurementSizeInBytes);
344 memset(sealing_binding_value.data, 0, kDiceMeasurementSizeInBytes);
345 sealing_binding_value.data[0] = kOwnerAppDomainProd;
356 size_t offset,
size_t *size) {
357 memset(cert_buffer, 0,
sizeof(cert_buffer));
360 perso_tlv_object_header_t objh;
362 TRY(flash_ctrl_info_read(page, offset, 1, cert_buffer));
363 memcpy(&objh, cert_buffer,
sizeof(perso_tlv_object_header_t));
364 PERSO_TLV_GET_FIELD(Objh, Size, objh, &obj_size);
369 "Inconsistent certificate perso LTV object header %02x %02x at "
371 cert_buffer[0], cert_buffer[1], page->
base_addr, offset);
374 if (obj_size >
sizeof(cert_buffer)) {
375 LOG_ERROR(
"Bad certificate perso LTV object size %d at page:offset %x:%x",
379 if ((obj_size + offset) > FLASH_CTRL_PARAM_BYTES_PER_PAGE) {
380 LOG_ERROR(
"Cert size overflow (%d + %d) page %x:%x", obj_size, offset,
387 TRY(flash_ctrl_info_read(page, offset, util_size_to_words(obj_size),
389 TRY(perso_tlv_get_cert_obj(cert_buffer, kBufferSize, &cert_obj));
400 static status_t hash_all_certs(
void) {
401 uint32_t cert_obj_size;
405 for (
size_t i = 0; i <
ARRAYSIZE(cert_flash_layout); i++) {
406 uint32_t page_offset = 0;
409 if (!curr_layout.
used) {
412 for (
size_t j = 0; j < curr_layout.
num_certs; j++) {
413 TRY(hash_certificate(curr_layout.
info_page, page_offset, &cert_obj_size));
414 page_offset += util_size_to_words(cert_obj_size) *
sizeof(uint32_t);
415 page_offset = util_round_up_to(page_offset, 3);
431 TRY(otbn_boot_app_load());
434 TRY(config_and_erase_certificate_flash_pages());
439 LOG_INFO(
"Waiting for certificate inputs ...");
440 TRY(ujson_deserialize_manuf_certgen_inputs_t(uj, &certgen_inputs));
443 memcpy(uds_endorsement_key_id.digest, certgen_inputs.dice_auth_key_key_id,
444 kCertKeyIdSizeInBytes);
447 TRY(entropy_complex_init());
448 TRY(kmac_keymgr_configure());
451 TRY(sc_keymgr_state_check(kScKeymgrStateReset));
452 sc_keymgr_advance_state();
453 TRY(sc_keymgr_state_check(kScKeymgrStateInit));
454 sc_keymgr_advance_state();
464 TRY(measure_otp_partition(kOtpPartitionCreatorSwCfg,
465 &otp_creator_sw_cfg_measurement,
467 TRY(measure_otp_partition(kOtpPartitionOwnerSwCfg,
468 &otp_owner_sw_cfg_measurement,
470 TRY(measure_otp_partition(kOtpPartitionRotCreatorAuthCodesign,
471 &otp_rot_creator_auth_codesign_measurement,
473 TRY(measure_otp_partition(kOtpPartitionRotCreatorAuthState,
474 &otp_rot_creator_auth_state_measurement,
480 size_t curr_cert_size = 0;
483 curr_cert_size = kUdsMaxTbsSizeBytes;
484 TRY(otbn_boot_cert_ecc_p256_keygen(kDiceKeyUds, &uds_pubkey_id,
492 TRY(dice_uds_tbs_cert_build(
493 &otp_creator_sw_cfg_measurement, &otp_owner_sw_cfg_measurement,
494 &otp_rot_creator_auth_codesign_measurement,
495 &otp_rot_creator_auth_state_measurement, &uds_key_ids, &curr_pubkey,
496 all_certs, &curr_cert_size));
499 uds_offset = perso_blob_to_host.next_free;
500 TRY(perso_tlv_push_cert_to_perso_blob(
502 kDiceCertFormat == kDiceCertFormatX509TcbInfo,
503 kDiceCertFormat, all_certs, curr_cert_size, &perso_blob_to_host));
504 LOG_INFO(
"Generated UDS certificate.");
507 curr_cert_size = kCdi0MaxCertSizeBytes;
508 compute_keymgr_owner_int_binding(&certgen_inputs);
509 TRY(sc_keymgr_owner_int_advance(&sealing_binding_value,
510 &attestation_binding_value,
512 TRY(otbn_boot_cert_ecc_p256_keygen(kDiceKeyCdi0, &cdi_0_pubkey_id,
514 TRY(dice_cdi_0_cert_build((
hmac_digest_t *)certgen_inputs.rom_ext_measurement,
515 certgen_inputs.rom_ext_security_version,
516 &cdi_0_key_ids, &curr_pubkey, all_certs,
518 cdi_0_offset = perso_blob_to_host.next_free;
521 TRY(perso_tlv_push_cert_to_perso_blob(
"CDI_0",
false,
522 kDiceCertFormat, all_certs,
523 curr_cert_size, &perso_blob_to_host));
524 LOG_INFO(
"Generated CDI_0 certificate.");
527 curr_cert_size = kCdi1MaxCertSizeBytes;
528 compute_keymgr_owner_binding(&certgen_inputs);
529 TRY(sc_keymgr_owner_advance(&sealing_binding_value,
530 &attestation_binding_value,
532 TRY(otbn_boot_cert_ecc_p256_keygen(kDiceKeyCdi1, &cdi_1_pubkey_id,
534 TRY(dice_cdi_1_cert_build(
537 certgen_inputs.owner_security_version, kOwnerAppDomainProd,
538 &cdi_1_key_ids, &curr_pubkey, all_certs, &curr_cert_size));
539 cdi_1_offset = perso_blob_to_host.next_free;
542 TRY(perso_tlv_push_cert_to_perso_blob(
"CDI_1",
false,
543 kDiceCertFormat, all_certs,
544 curr_cert_size, &perso_blob_to_host));
545 LOG_INFO(
"Generated CDI_1 certificate.");
552 static size_t max_available(
void) {
553 if (perso_blob_from_host.next_free >
sizeof(perso_blob_from_host.body))
556 return sizeof(perso_blob_from_host.body) - perso_blob_from_host.next_free;
570 static status_t extract_next_cert(uint8_t **dest,
size_t *free_room) {
573 if (perso_blob_from_host.next_free >
sizeof(perso_blob_from_host.body)) {
578 while (perso_blob_from_host.num_objs != 0) {
582 rom_error_t err = perso_tlv_get_cert_obj(
583 perso_blob_from_host.body + perso_blob_from_host.next_free,
584 max_available(), &block);
588 case kErrorPersoTlvCertObjNotFound: {
590 perso_blob_from_host.next_free += block.
obj_size;
591 perso_blob_from_host.num_objs--;
601 return RESOURCE_EXHAUSTED();
604 uint8_t *dest_p = *dest;
610 *free_room = *free_room - block.
obj_size;
613 perso_blob_from_host.next_free += block.
obj_size;
614 perso_blob_from_host.num_objs--;
621 static status_t write_cert_to_flash_info_page(
623 uint8_t *cert_data, uint32_t page_offset, uint32_t cert_write_size_bytes,
624 uint32_t cert_write_size_words) {
625 if ((page_offset + cert_write_size_bytes) > FLASH_CTRL_PARAM_BYTES_PER_PAGE) {
626 LOG_ERROR(
"%s %s certificate did not fit into the info page.",
628 return OUT_OF_RANGE();
630 if (
sizeof(cert_buffer) < cert_write_size_bytes) {
631 LOG_ERROR(
"%s %s certificate did not fit into the buffer.",
633 return OUT_OF_RANGE();
636 memset(cert_buffer, 0, cert_write_size_bytes);
645 TRY(flash_ctrl_info_write(layout->
info_page, page_offset,
646 cert_write_size_words, cert_buffer));
658 LOG_INFO(
"Exporting TBS certificates ...");
660 RESP_OK(ujson_serialize_perso_blob_t, uj, &perso_blob_to_host);
665 LOG_INFO(
"Importing endorsed certificates ...");
666 TRY(ujson_deserialize_perso_blob_t(uj, &perso_blob_from_host));
681 perso_blob_from_host.next_free = 0;
684 uint8_t *next_cert = all_certs;
686 size_t free_room =
sizeof(all_certs);
694 size_t cert_offsets[3] = {uds_offset, cdi_0_offset, cdi_1_offset};
695 size_t cert_offsets_count = 3;
696 if (kDiceCertFormat == kDiceCertFormatX509TcbInfo) {
698 TRY(extract_next_cert(&next_cert, &free_room));
701 cert_offsets[0] = cert_offsets[1];
702 cert_offsets[1] = cert_offsets[2];
703 cert_offsets_count = 2;
707 for (
size_t i = 0; i < cert_offsets_count; i++) {
708 size_t offset = cert_offsets[i];
709 TRY(perso_tlv_get_cert_obj(perso_blob_to_host.body + offset,
710 sizeof(perso_blob_to_host.body) - offset,
713 return RESOURCE_EXHAUSTED();
722 while (perso_blob_from_host.num_objs)
723 TRY(extract_next_cert(&next_cert, &free_room));
730 next_cert = all_certs;
731 free_room =
sizeof(all_certs);
732 for (
size_t i = 0; i <
ARRAYSIZE(cert_flash_layout); i++) {
734 uint32_t page_offset = 0;
737 if (!curr_layout.
used) {
744 for (
size_t j = 0; j < curr_layout.
num_certs; j++) {
746 TRY(perso_tlv_get_cert_obj(next_cert, free_room, &block));
748 uint32_t cert_size_words = util_size_to_words(block.
obj_size);
749 uint32_t cert_size_bytes_ru = cert_size_words *
sizeof(uint32_t);
750 TRY(write_cert_to_flash_info_page(&curr_layout, &block, next_cert,
751 page_offset, cert_size_bytes_ru,
755 page_offset += cert_size_bytes_ru;
759 page_offset = util_round_up_to(page_offset, 3);
765 LOG_INFO(
"Finished importing certificates.");
770 static status_t send_final_hash(
ujson_t *uj, serdes_sha256_hash_t *hash) {
771 return RESP_OK(ujson_serialize_serdes_sha256_hash_t, uj, hash);
780 otp_partition_t partition) {
782 TRY(measure_otp_partition(partition, &final_measurement,
785 TRY_CHECK(final_measurement.digest[1] == measurement->digest[1]);
786 TRY_CHECK(final_measurement.digest[0] == measurement->digest[0]);
797 uint64_t expected_digest = otp_read64(offset);
798 uint32_t digest_hi = expected_digest >> 32;
799 uint32_t digest_lo = expected_digest & UINT32_MAX;
800 TRY_CHECK(digest_hi == measurement->digest[1]);
801 TRY_CHECK(digest_lo == measurement->digest[0]);
805 static status_t finalize_otp_partitions(
void) {
808 TRY(check_next_slot_bootable());
811 if (!status_ok(manuf_individualize_device_owner_sw_cfg_check(&otp_ctrl))) {
812 TRY(manuf_individualize_device_field_cfg(
813 &otp_ctrl, OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET));
814 TRY(check_otp_measurement_pre_lock(&otp_owner_sw_cfg_measurement,
815 kOtpPartitionOwnerSwCfg));
816 TRY(manuf_individualize_device_owner_sw_cfg_lock(&otp_ctrl));
818 TRY(check_otp_measurement_post_lock(
819 &otp_owner_sw_cfg_measurement,
820 OTP_CTRL_PARAM_OWNER_SW_CFG_DIGEST_OFFSET));
823 if (!status_ok(manuf_individualize_device_creator_sw_cfg_check(&otp_ctrl))) {
824 TRY(manuf_individualize_device_field_cfg(
825 &otp_ctrl, OTP_CTRL_PARAM_CREATOR_SW_CFG_MANUF_STATE_OFFSET));
826 TRY(manuf_individualize_device_field_cfg(
827 &otp_ctrl, OTP_CTRL_PARAM_CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN_OFFSET));
828 TRY(check_otp_measurement_pre_lock(&otp_creator_sw_cfg_measurement,
829 kOtpPartitionCreatorSwCfg));
830 TRY(manuf_individualize_device_creator_sw_cfg_lock(&otp_ctrl));
832 TRY(check_otp_measurement_post_lock(
833 &otp_creator_sw_cfg_measurement,
834 OTP_CTRL_PARAM_CREATOR_SW_CFG_DIGEST_OFFSET));
840 CHECK_STATUS_OK(peripheral_handles_init());
841 ujson_t uj = ujson_ottf_console();
843 CHECK_STATUS_OK(lc_ctrl_testutils_operational_state_check(&lc_ctrl));
844 CHECK_STATUS_OK(personalize_otp_and_flash_secrets(&uj));
845 CHECK_STATUS_OK(personalize_gen_dice_certificates(&uj));
849 .certgen_inputs = &certgen_inputs,
850 .perso_blob_to_host = &perso_blob_to_host,
851 .cert_flash_layout = cert_flash_layout,
852 .flash_ctrl_handle = &flash_ctrl_state,
853 .uds_pubkey = &uds_pubkey,
854 .uds_pubkey_id = &uds_pubkey_id,
855 .otp_creator_sw_cfg_measurement = &otp_creator_sw_cfg_measurement,
856 .otp_owner_sw_cfg_measurement = &otp_owner_sw_cfg_measurement,
857 .otp_rot_creator_auth_codesign_measurement =
858 &otp_rot_creator_auth_codesign_measurement,
859 .otp_rot_creator_auth_state_measurement =
860 &otp_rot_creator_auth_state_measurement};
861 CHECK_STATUS_OK(personalize_extension_pre_cert_endorse(&pre_endorse));
863 CHECK_STATUS_OK(personalize_endorse_certificates(&uj));
864 CHECK_STATUS_OK(hash_all_certs());
868 .perso_blob_from_host = &perso_blob_from_host,
869 .cert_flash_layout = cert_flash_layout};
870 CHECK_STATUS_OK(personalize_extension_post_cert_endorse(&post_endorse));
873 serdes_sha256_hash_t hash;
874 hmac_sha256_process();
876 CHECK_STATUS_OK(send_final_hash(&uj, &hash));
877 LOG_INFO(
"SHA256 hash of all perso objects: %08x%08x%08x%08x%08x%08x%08x%08x",
878 hash.data[7], hash.data[6], hash.data[5], hash.data[4], hash.data[3],
879 hash.data[2], hash.data[1], hash.data[0]);
881 CHECK_STATUS_OK(finalize_otp_partitions());