Software APIs
tpm_personalize_ext.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "perso_tlv_data.h"
8 #include "sw/device/lib/testing/test_framework/status.h"
9 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
10 #include "sw/device/silicon_creator/lib/attestation.h"
11 #include "sw/device/silicon_creator/lib/cert/cert.h"
12 #include "sw/device/silicon_creator/lib/cert/tpm.h"
13 #include "sw/device/silicon_creator/lib/cert/tpm_ek.h" // Generated.
14 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
15 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
16 #include "sw/device/silicon_creator/lib/otbn_boot_services.h"
17 #include "sw/device/silicon_creator/manuf/base/personalize_ext.h"
18 #include "sw/device/silicon_creator/manuf/lib/personalize.h"
19 
21 
22 /**
23  * Peripheral handles.
24  */
25 static dif_flash_ctrl_state_t flash_ctrl_state;
26 
27 /**
28  * Certificate data.
29  */
30 static hmac_digest_t tpm_endorsement_key_id;
31 static hmac_digest_t tpm_pubkey_id;
32 static cert_key_id_pair_t tpm_key_ids = {.endorsement = &tpm_endorsement_key_id,
33  .cert = &tpm_pubkey_id};
34 static ecdsa_p256_public_key_t curr_pubkey = {.x = {0}, .y = {0}};
35 
36 /**
37  * Initializes all DIF handles used in this program.
38  */
39 static status_t peripheral_handles_init(void) {
41  &flash_ctrl_state,
43  return OK_STATUS();
44 }
45 
46 /**
47  * Configures flash info pages to store device certificates.
48  */
49 static status_t config_and_erase_tpm_certificate_flash_pages(void) {
50  flash_ctrl_cert_info_page_creator_cfg(&kFlashCtrlInfoPageOwnerReserved6);
51  TRY(flash_ctrl_info_erase(&kFlashCtrlInfoPageOwnerReserved6,
52  kFlashCtrlEraseTypePage));
53  return OK_STATUS();
54 }
55 
56 // Temp buffer for storing generated EK certificate.
57 static uint8_t cert_buffer[kTpmEkMaxTbsSizeBytes];
58 
59 static status_t personalize_gen_tpm_ek_certificate(
60  manuf_certgen_inputs_t *certgen_inputs, perso_blob_t *perso_blob,
61  cert_flash_info_layout_t *cert_flash_layout) {
62  size_t curr_cert_size = 0;
63  // Set the endorsement key ID.
64  memcpy(tpm_endorsement_key_id.digest, certgen_inputs->ext_auth_key_key_id,
65  kCertKeyIdSizeInBytes);
66 
67  // Set the flash info page layout.
68  cert_flash_layout[kCertFlashLayoutExt0Idx].used = true;
69  cert_flash_layout[kCertFlashLayoutExt0Idx].group_name = "TPM";
70  cert_flash_layout[kCertFlashLayoutExt0Idx].num_certs = 1;
71 
72  // Provision TPM keygen seeds to flash info.
73  TRY(manuf_personalize_flash_asymm_key_seed(
74  &flash_ctrl_state, kFlashInfoFieldTpmEkAttestationKeySeed,
75  kAttestationSeedWords));
76 
77  // Generate TPM EK keys and (TBS) cert.
78  TRY(otbn_boot_cert_ecc_p256_keygen(kTpmKeyEk, &tpm_pubkey_id, &curr_pubkey));
79 
80  curr_cert_size = sizeof(cert_buffer);
81  TRY(tpm_ek_tbs_cert_build(&tpm_key_ids, &curr_pubkey, cert_buffer,
82  &curr_cert_size));
83  TRY(perso_tlv_push_cert_to_perso_blob("TPM EK", /*needs_endorsement=*/true,
84  kDiceCertFormatX509TcbInfo, cert_buffer,
85  curr_cert_size, perso_blob));
86  return OK_STATUS();
87 }
88 
89 status_t personalize_extension_pre_cert_endorse(
91  LOG_INFO("Running TPM perso extension ...");
92  TRY(peripheral_handles_init());
93  TRY(config_and_erase_tpm_certificate_flash_pages());
94  TRY(personalize_gen_tpm_ek_certificate(pre_params->certgen_inputs,
95  pre_params->perso_blob_to_host,
96  pre_params->cert_flash_layout));
97  return OK_STATUS();
98 }
99 
100 status_t personalize_extension_post_cert_endorse(
102  /* Empty because it is unused but we still need to link to something. */
103  return OK_STATUS();
104 }