5 #include "sw/device/silicon_creator/lib/cert/dice_chain.h"
10 #include "sw/device/lib/crypto/drivers/entropy.h"
11 #include "sw/device/silicon_creator/lib/base/boot_measurements.h"
13 #include "sw/device/silicon_creator/lib/base/static_dice_cdi_0.h"
14 #include "sw/device/silicon_creator/lib/base/util.h"
15 #include "sw/device/silicon_creator/lib/cert/dice.h"
16 #include "sw/device/silicon_creator/lib/dbg_print.h"
17 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
18 #include "sw/device/silicon_creator/lib/drivers/kmac.h"
19 #include "sw/device/silicon_creator/lib/error.h"
20 #include "sw/device/silicon_creator/lib/manifest.h"
21 #include "sw/device/silicon_creator/lib/otbn_boot_services.h"
22 #include "sw/device/silicon_creator/lib/ownership/datatypes.h"
23 #include "sw/device/silicon_creator/manuf/base/perso_tlv_data.h"
25 #include "flash_ctrl_regs.h"
32 kScratchCertSizeBytes = FLASH_CTRL_PARAM_BYTES_PER_PAGE,
45 uint8_t
data[FLASH_CTRL_PARAM_BYTES_PER_PAGE];
104 .cert = &static_dice_cdi_0.cdi_0_pubkey_id,
110 static size_t dice_chain_get_tail_size(
void) {
117 static uint8_t *dice_chain_get_tail_buffer(
void) {
122 static void dice_chain_reset_cert_obj(
void) {
132 static void dice_chain_next_cert_obj(
void) {
137 cert_size = util_size_to_words(cert_size) *
sizeof(uint32_t);
138 cert_size = util_round_up_to(cert_size, 3);
146 dice_chain_reset_cert_obj();
162 static rom_error_t dice_chain_load_cert_obj(
const char *name,
165 perso_tlv_get_cert_obj(dice_chain_get_tail_buffer(),
168 if (err != kErrorOk) {
170 dice_chain_reset_cert_obj();
173 if (err == kErrorPersoTlvCertObjNotFound) {
181 RETURN_IF_ERROR(err);
192 RETURN_IF_ERROR(dice_cert_check_valid(
200 static rom_error_t dice_chain_skip_cert_obj(
const char *name,
202 RETURN_IF_ERROR(dice_chain_load_cert_obj(NULL, 0));
204 dice_chain_next_cert_obj();
211 static rom_error_t dice_chain_load_flash(
220 RETURN_IF_ERROR(dice_chain_flush_flash());
223 static_assert(
sizeof(
dice_chain.
data) == FLASH_CTRL_PARAM_BYTES_PER_PAGE,
224 "Invalid dice_chain buffer size");
225 RETURN_IF_ERROR(flash_ctrl_info_read_zeros_on_read_error(
227 FLASH_CTRL_PARAM_BYTES_PER_PAGE /
sizeof(uint32_t),
234 dice_chain_reset_cert_obj();
241 static rom_error_t dice_chain_push_cert(
const char *name,
const uint8_t *cert,
242 const size_t cert_size) {
247 memset(dice_chain_get_tail_buffer(), 0, dice_chain_get_tail_size());
250 size_t cert_page_left = dice_chain_get_tail_size();
252 perso_tlv_cert_obj_build(name, kPersoObjectTypeX509Cert, cert, cert_size,
253 dice_chain_get_tail_buffer(), &cert_page_left));
256 RETURN_IF_ERROR(perso_tlv_get_cert_obj(dice_chain_get_tail_buffer(),
257 dice_chain_get_tail_size(),
259 dice_chain_next_cert_obj();
263 rom_error_t dice_chain_attestation_silicon(
void) {
267 HARDENED_RETURN_IF_ERROR((rom_error_t)entropy_complex_init().value);
268 HARDENED_RETURN_IF_ERROR(kmac_keymgr_configure());
272 const uint16_t kScKeymgrEntropyReseedInterval = UINT16_MAX;
273 sc_keymgr_entropy_reseed_interval_set(kScKeymgrEntropyReseedInterval);
279 RETURN_IF_ERROR(sc_keymgr_state_check(kScKeymgrStateReset));
280 sc_keymgr_advance_state();
281 RETURN_IF_ERROR(sc_keymgr_state_check(kScKeymgrStateInit));
284 sc_keymgr_advance_state();
285 HARDENED_RETURN_IF_ERROR(sc_keymgr_state_check(kScKeymgrStateCreatorRootKey));
286 HARDENED_RETURN_IF_ERROR(otbn_boot_cert_ecc_p256_keygen(
287 kDiceKeyUds, &static_dice_cdi_0.uds_pubkey_id,
288 &static_dice_cdi_0.uds_pubkey));
291 RETURN_IF_ERROR(otbn_boot_attestation_key_save(
298 rom_error_t dice_chain_attestation_creator(
305 kScKeymgrSecMmioOwnerIntMaxVerSet);
306 HARDENED_RETURN_IF_ERROR(sc_keymgr_owner_int_advance(
310 HARDENED_RETURN_IF_ERROR(otbn_boot_cert_ecc_p256_keygen(
311 kDiceKeyCdi0, &static_dice_cdi_0.cdi_0_pubkey_id,
312 &static_dice_cdi_0.cdi_0_pubkey));
315 RETURN_IF_ERROR(dice_chain_load_flash(&kFlashCtrlInfoPageDiceCerts));
318 RETURN_IF_ERROR(dice_chain_skip_cert_obj(
"UDS", 4));
321 RETURN_IF_ERROR(dice_chain_load_cert_obj(
"CDI_0", 6));
323 dbg_puts(
"CDI_0 certificate not valid. Updating it ...\r\n");
325 static_dice_cdi_0.cert_size =
sizeof(static_dice_cdi_0.cert_data);
326 HARDENED_RETURN_IF_ERROR(dice_cdi_0_cert_build(
329 &static_dice_cdi_0.cdi_0_pubkey, static_dice_cdi_0.cert_data,
330 &static_dice_cdi_0.cert_size));
333 HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_key_save(
338 sc_keymgr_sw_binding_unlock_wait();
345 static rom_error_t dice_chain_attestation_check_uds(
void) {
347 RETURN_IF_ERROR(dice_chain_load_flash(&kFlashCtrlInfoPageFactoryCerts));
353 RETURN_IF_ERROR(dice_chain_load_cert_obj(
"UDS", 4));
364 dbg_puts(
"error: UDS certificate not valid\r\n");
372 static rom_error_t dice_chain_attestation_check_cdi_0(
void) {
374 RETURN_IF_ERROR(dice_chain_load_flash(&kFlashCtrlInfoPageDiceCerts));
377 RETURN_IF_ERROR(dice_chain_skip_cert_obj(
"UDS", 4));
383 RETURN_IF_ERROR(dice_chain_load_cert_obj(
"CDI_0", 6));
385 dbg_puts(
"warning: CDI_0 certificate not valid; updating\r\n");
387 RETURN_IF_ERROR(dice_chain_push_cert(
"CDI_0", static_dice_cdi_0.cert_data,
388 static_dice_cdi_0.cert_size));
391 dice_chain_next_cert_obj();
397 rom_error_t dice_chain_attestation_owner(
400 owner_app_domain_t key_domain) {
402 RETURN_IF_ERROR(dice_chain_attestation_check_uds());
403 RETURN_IF_ERROR(dice_chain_attestation_check_cdi_0());
407 kScKeymgrSecMmioOwnerIntMaxVerSet);
410 "Expect the keymgr binding value to be the same size as a sha256 digest");
416 hmac_sha256_configure(
false);
418 hmac_sha256_update(bl0_measurement,
sizeof(*bl0_measurement));
419 hmac_sha256_update(owner_measurement,
sizeof(*owner_measurement));
420 hmac_sha256_process();
421 hmac_sha256_final(&attest_measurement);
423 HARDENED_RETURN_IF_ERROR(sc_keymgr_owner_advance(
427 HARDENED_RETURN_IF_ERROR(otbn_boot_cert_ecc_p256_keygen(
431 RETURN_IF_ERROR(dice_chain_load_cert_obj(
"CDI_1", 6));
433 dbg_puts(
"CDI_1 certificate not valid. Updating it ...\r\n");
435 size_t updated_cert_size = kScratchCertSizeBytes;
437 HARDENED_RETURN_IF_ERROR(dice_cdi_1_cert_build(
441 &updated_cert_size));
446 dice_chain_next_cert_obj();
449 HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_key_save(
455 sc_keymgr_sw_binding_unlock_wait();
461 rom_error_t dice_chain_flush_flash(
void) {
466 static_assert(
sizeof(
dice_chain.
data) == FLASH_CTRL_PARAM_BYTES_PER_PAGE,
467 "Invalid dice_chain buffer size");
468 RETURN_IF_ERROR(flash_ctrl_info_write(
471 FLASH_CTRL_PARAM_BYTES_PER_PAGE /
sizeof(uint32_t),
473 dbg_puts(
"Flushed dice cert page\r\n");
479 rom_error_t dice_chain_init(
void) {
487 dice_chain_reset_cert_obj();
490 flash_ctrl_cert_info_page_creator_cfg(&kFlashCtrlInfoPageDiceCerts);
491 flash_ctrl_info_cfg_set(&kFlashCtrlInfoPageFactoryCerts,
492 kCertificateInfoPageCfg);
493 flash_ctrl_cert_info_page_owner_restrict(&kFlashCtrlInfoPageFactoryCerts);