10
10
#include "sw/device/lib/crypto/drivers/entropy.h"
11
11
#include "sw/device/silicon_creator/lib/base/boot_measurements.h"
12
12
#include "sw/device/silicon_creator/lib/base/sec_mmio.h"
13
+ #include "sw/device/silicon_creator/lib/base/static_dice_cdi_0.h"
13
14
#include "sw/device/silicon_creator/lib/base/util.h"
14
15
#include "sw/device/silicon_creator/lib/cert/dice.h"
15
16
#include "sw/device/silicon_creator/lib/dbg_print.h"
@@ -97,6 +98,11 @@ typedef struct dice_chain {
97
98
98
99
static dice_chain_t dice_chain ;
99
100
101
+ cert_key_id_pair_t dice_chain_cdi_0_key_ids = (cert_key_id_pair_t ){
102
+ .endorsement = & static_dice_cdi_0 .uds_pubkey_id ,
103
+ .cert = & static_dice_cdi_0 .cdi_0_pubkey_id ,
104
+ };
105
+
100
106
// Get the size of the remaining tail space that is not processed yet.
101
107
OT_WARN_UNUSED_RESULT
102
108
OT_NOINLINE
@@ -277,31 +283,13 @@ rom_error_t dice_chain_attestation_silicon(void) {
277
283
sc_keymgr_advance_state ();
278
284
HARDENED_RETURN_IF_ERROR (sc_keymgr_state_check (kScKeymgrStateCreatorRootKey ));
279
285
HARDENED_RETURN_IF_ERROR (otbn_boot_cert_ecc_p256_keygen (
280
- kDiceKeyUds , & dice_chain .subject_pubkey_id , & dice_chain .subject_pubkey ));
281
-
282
- // Switch page for the factory provisioned UDS cert.
283
- RETURN_IF_ERROR (dice_chain_load_flash (& kFlashCtrlInfoPageFactoryCerts ));
284
-
285
- // Check if the UDS cert is valid.
286
- RETURN_IF_ERROR (dice_chain_load_cert_obj ("UDS" , /*name_size=*/ 4 ));
287
- if (dice_chain .cert_valid == kHardenedBoolFalse ) {
288
- // The UDS key ID (and cert itself) should never change unless:
289
- // 1. there is a hardware issue / the page has been corrupted, or
290
- // 2. the cert has not yet been provisioned.
291
- //
292
- // In both cases, we do nothing, and boot normally, later attestation
293
- // attempts will fail in a detectable manner.
294
- dbg_puts ("Warning: UDS certificate not valid.\r\n" );
295
- } else {
296
- // Cert is valid, move to the next one.
297
- dice_chain_next_cert_obj ();
298
- }
286
+ kDiceKeyUds , & static_dice_cdi_0 .uds_pubkey_id ,
287
+ & dice_chain .subject_pubkey ));
299
288
300
289
// Save UDS key for signing next stage cert.
301
290
RETURN_IF_ERROR (otbn_boot_attestation_key_save (
302
291
kDiceKeyUds .keygen_seed_idx , kDiceKeyUds .type ,
303
292
* kDiceKeyUds .keymgr_diversifier ));
304
- dice_chain .endorsement_pubkey_id = dice_chain .subject_pubkey_id ;
305
293
306
294
return kErrorOk ;
307
295
}
@@ -319,7 +307,8 @@ rom_error_t dice_chain_attestation_creator(
319
307
/*attest_binding=*/ rom_ext_measurement ,
320
308
rom_ext_manifest -> max_key_version ));
321
309
HARDENED_RETURN_IF_ERROR (otbn_boot_cert_ecc_p256_keygen (
322
- kDiceKeyCdi0 , & dice_chain .subject_pubkey_id , & dice_chain .subject_pubkey ));
310
+ kDiceKeyCdi0 , & static_dice_cdi_0 .cdi_0_pubkey_id ,
311
+ & dice_chain .subject_pubkey ));
323
312
324
313
// Switch page for the device generated CDI_0.
325
314
RETURN_IF_ERROR (dice_chain_load_flash (& kFlashCtrlInfoPageDiceCerts ));
@@ -332,33 +321,83 @@ rom_error_t dice_chain_attestation_creator(
332
321
if (dice_chain .cert_valid == kHardenedBoolFalse ) {
333
322
dbg_puts ("CDI_0 certificate not valid. Updating it ...\r\n" );
334
323
// Update the cert page buffer.
335
- size_t updated_cert_size = kScratchCertSizeBytes ;
336
- HARDENED_RETURN_IF_ERROR (
337
- dice_cdi_0_cert_build ((hmac_digest_t * )rom_ext_measurement -> data ,
338
- rom_ext_manifest -> security_version ,
339
- & dice_chain .key_ids , & dice_chain .subject_pubkey ,
340
- dice_chain .scratch_cert , & updated_cert_size ));
341
- RETURN_IF_ERROR (dice_chain_push_cert ("CDI_0" , dice_chain .scratch_cert ,
342
- updated_cert_size ));
324
+ static_dice_cdi_0 .cert_size = sizeof (static_dice_cdi_0 .cert_data );
325
+ HARDENED_RETURN_IF_ERROR (dice_cdi_0_cert_build (
326
+ (hmac_digest_t * )rom_ext_measurement -> data ,
327
+ rom_ext_manifest -> security_version , & dice_chain_cdi_0_key_ids ,
328
+ & dice_chain .subject_pubkey , static_dice_cdi_0 .cert_data ,
329
+ & static_dice_cdi_0 .cert_size ));
343
330
} else {
344
- // Cert is valid, move to the next one.
345
- dice_chain_next_cert_obj ();
346
-
347
331
// Replace UDS with CDI_0 key for endorsing next stage cert.
348
332
HARDENED_RETURN_IF_ERROR (otbn_boot_attestation_key_save (
349
333
kDiceKeyCdi0 .keygen_seed_idx , kDiceKeyCdi0 .type ,
350
334
* kDiceKeyCdi0 .keymgr_diversifier ));
351
335
}
352
- dice_chain .endorsement_pubkey_id = dice_chain .subject_pubkey_id ;
353
336
354
337
sc_keymgr_sw_binding_unlock_wait ();
355
338
356
339
return kErrorOk ;
357
340
}
358
341
342
+ // Compare the UDS identity in the static critical section to the UDS cert
343
+ // cached in the flash.
344
+ static rom_error_t dice_chain_attestation_check_uds (void ) {
345
+ // Switch page for the factory provisioned UDS cert.
346
+ RETURN_IF_ERROR (dice_chain_load_flash (& kFlashCtrlInfoPageFactoryCerts ));
347
+
348
+ // Check if the UDS cert is valid.
349
+ dice_chain .endorsement_pubkey_id = static_dice_cdi_0 .uds_pubkey_id ;
350
+ dice_chain .subject_pubkey_id = static_dice_cdi_0 .uds_pubkey_id ;
351
+ RETURN_IF_ERROR (dice_chain_load_cert_obj ("UDS" , /*name_size=*/ 4 ));
352
+ if (dice_chain .cert_valid == kHardenedBoolFalse ) {
353
+ // The UDS key ID (and cert itself) should never change unless:
354
+ // 1. there is a hardware issue / the page has been corrupted, or
355
+ // 2. the cert has not yet been provisioned.
356
+ //
357
+ // In both cases, we do nothing, and boot normally, later attestation
358
+ // attempts will fail in a detectable manner.
359
+
360
+ // CAUTION: This error message should match the one in
361
+ // //sw/host/provisioning/ft_lib/src/lib.rs
362
+ dbg_puts ("error: UDS certificate not valid\r\n" );
363
+ }
364
+
365
+ return kErrorOk ;
366
+ }
367
+
368
+ // Compare the CDI_0 identity in the static critical section to the CDI_0 cert
369
+ // cached in the flash, and refresh the cache if invalid.
370
+ static rom_error_t dice_chain_attestation_check_cdi_0 (void ) {
371
+ // Switch page for the device CDI chain.
372
+ RETURN_IF_ERROR (dice_chain_load_flash (& kFlashCtrlInfoPageDiceCerts ));
373
+
374
+ // Seek to skip previous objects.
375
+ RETURN_IF_ERROR (dice_chain_skip_cert_obj ("UDS" , /*name_size=*/ 4 ));
376
+
377
+ // Refresh cdi 0 if invalid
378
+ dice_chain .endorsement_pubkey_id = static_dice_cdi_0 .cdi_0_pubkey_id ;
379
+ dice_chain .subject_pubkey_id = static_dice_cdi_0 .cdi_0_pubkey_id ;
380
+ RETURN_IF_ERROR (dice_chain_load_cert_obj ("CDI_0" , /*name_size=*/ 6 ));
381
+ if (dice_chain .cert_valid == kHardenedBoolFalse ) {
382
+ dbg_puts ("warning: CDI_0 certificate not valid; updating\r\n" );
383
+ // Update the cert page buffer.
384
+ RETURN_IF_ERROR (dice_chain_push_cert ("CDI_0" , static_dice_cdi_0 .cert_data ,
385
+ static_dice_cdi_0 .cert_size ));
386
+ } else {
387
+ // Cert is valid, move to the next one.
388
+ dice_chain_next_cert_obj ();
389
+ }
390
+
391
+ return kErrorOk ;
392
+ }
393
+
359
394
rom_error_t dice_chain_attestation_owner (
360
395
const manifest_t * owner_manifest , keymgr_binding_value_t * bl0_measurement ,
361
396
hmac_digest_t * owner_measurement , keymgr_binding_value_t * sealing_binding ) {
397
+ // Handles the certificates from the immutable rom_ext first.
398
+ RETURN_IF_ERROR (dice_chain_attestation_check_uds ());
399
+ RETURN_IF_ERROR (dice_chain_attestation_check_cdi_0 ());
400
+
362
401
// Generate CDI_1 attestation keys and (potentially) update certificate.
363
402
SEC_MMIO_WRITE_INCREMENT (kScKeymgrSecMmioSwBindingSet +
364
403
kScKeymgrSecMmioOwnerIntMaxVerSet );
@@ -384,14 +423,7 @@ rom_error_t dice_chain_attestation_owner(
384
423
HARDENED_RETURN_IF_ERROR (otbn_boot_cert_ecc_p256_keygen (
385
424
kDiceKeyCdi1 , & dice_chain .subject_pubkey_id , & dice_chain .subject_pubkey ));
386
425
387
- // Switch page for the device generated CDI_1.
388
- RETURN_IF_ERROR (dice_chain_load_flash (& kFlashCtrlInfoPageDiceCerts ));
389
-
390
- // Seek to skip previous objects.
391
- RETURN_IF_ERROR (dice_chain_skip_cert_obj ("UDS" , /*name_size=*/ 4 ));
392
- RETURN_IF_ERROR (dice_chain_skip_cert_obj ("CDI_0" , /*name_size=*/ 6 ));
393
-
394
- // Check if the current CDI_0 cert is valid.
426
+ // Check if the current CDI_1 cert is valid.
395
427
RETURN_IF_ERROR (dice_chain_load_cert_obj ("CDI_1" , /*name_size=*/ 6 ));
396
428
if (dice_chain .cert_valid == kHardenedBoolFalse ) {
397
429
dbg_puts ("CDI_1 certificate not valid. Updating it ...\r\n" );
0 commit comments