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));
324 static_dice_cdi_0.cert_size =
sizeof(static_dice_cdi_0.cert_data);
325 HARDENED_RETURN_IF_ERROR(dice_cdi_0_cert_build(
328 &static_dice_cdi_0.cdi_0_pubkey, static_dice_cdi_0.cert_data,
329 &static_dice_cdi_0.cert_size));
332 HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_key_save(
337 sc_keymgr_sw_binding_unlock_wait();
344 static rom_error_t dice_chain_attestation_check_uds(
void) {
346 RETURN_IF_ERROR(dice_chain_load_flash(&kFlashCtrlInfoPageFactoryCerts));
352 RETURN_IF_ERROR(dice_chain_load_cert_obj(
"UDS", 4));
363 dbg_puts(
"error: UDS certificate not valid\r\n");
371 static rom_error_t dice_chain_attestation_check_cdi_0(
void) {
373 RETURN_IF_ERROR(dice_chain_load_flash(&kFlashCtrlInfoPageDiceCerts));
376 RETURN_IF_ERROR(dice_chain_skip_cert_obj(
"UDS", 4));
382 RETURN_IF_ERROR(dice_chain_load_cert_obj(
"CDI_0", 6));
384 dbg_puts(
"warning: CDI_0 certificate not valid; updating\r\n");
386 RETURN_IF_ERROR(dice_chain_push_cert(
"CDI_0", static_dice_cdi_0.cert_data,
387 static_dice_cdi_0.cert_size));
390 dice_chain_next_cert_obj();
396 rom_error_t dice_chain_attestation_owner(
399 owner_app_domain_t key_domain) {
401 RETURN_IF_ERROR(dice_chain_attestation_check_uds());
402 RETURN_IF_ERROR(dice_chain_attestation_check_cdi_0());
406 kScKeymgrSecMmioOwnerIntMaxVerSet);
409 "Expect the keymgr binding value to be the same size as a sha256 digest");
415 hmac_sha256_configure(
false);
417 hmac_sha256_update(bl0_measurement,
sizeof(*bl0_measurement));
418 hmac_sha256_update(owner_measurement,
sizeof(*owner_measurement));
419 hmac_sha256_process();
420 hmac_sha256_final(&attest_measurement);
422 HARDENED_RETURN_IF_ERROR(sc_keymgr_owner_advance(
426 HARDENED_RETURN_IF_ERROR(otbn_boot_cert_ecc_p256_keygen(
430 RETURN_IF_ERROR(dice_chain_load_cert_obj(
"CDI_1", 6));
432 dbg_puts(
"CDI_1 certificate not valid. Updating it ...\r\n");
434 size_t updated_cert_size = kScratchCertSizeBytes;
436 HARDENED_RETURN_IF_ERROR(dice_cdi_1_cert_build(
440 &updated_cert_size));
445 dice_chain_next_cert_obj();
448 HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_key_save(
454 sc_keymgr_sw_binding_unlock_wait();
460 rom_error_t dice_chain_flush_flash(
void) {
465 static_assert(
sizeof(
dice_chain.
data) == FLASH_CTRL_PARAM_BYTES_PER_PAGE,
466 "Invalid dice_chain buffer size");
467 RETURN_IF_ERROR(flash_ctrl_info_write(
470 FLASH_CTRL_PARAM_BYTES_PER_PAGE /
sizeof(uint32_t),
477 rom_error_t dice_chain_init(
void) {
485 dice_chain_reset_cert_obj();
488 flash_ctrl_cert_info_page_creator_cfg(&kFlashCtrlInfoPageDiceCerts);
489 flash_ctrl_info_cfg_set(&kFlashCtrlInfoPageFactoryCerts,
490 kCertificateInfoPageCfg);
491 flash_ctrl_cert_info_page_owner_restrict(&kFlashCtrlInfoPageFactoryCerts);