8 #include "sw/device/silicon_creator/lib/base/util.h"
9 #include "sw/device/silicon_creator/lib/cert/cbor.h"
10 #include "sw/device/silicon_creator/lib/cert/cert.h"
11 #include "sw/device/silicon_creator/lib/cert/cwt_cose_key.h"
12 #include "sw/device/silicon_creator/lib/cert/cwt_dice_chain_entry.h"
13 #include "sw/device/silicon_creator/lib/cert/cwt_dice_chain_entry_input.h"
14 #include "sw/device/silicon_creator/lib/cert/cwt_dice_chain_entry_payload.h"
15 #include "sw/device/silicon_creator/lib/cert/dice.h"
16 #include "sw/device/silicon_creator/lib/cert/dice_keys.h"
17 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
18 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
19 #include "sw/device/silicon_creator/lib/drivers/otp.h"
20 #include "sw/device/silicon_creator/lib/error.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/lib/sigverify/ecdsa_p256_key.h"
24 #include "sw/device/silicon_creator/manuf/base/perso_tlv_data.h"
26 #include "otp_ctrl_regs.h"
28 const dice_cert_format_t kDiceCertFormat = kDiceCertFormatCWTAndroid;
30 enum config_desc_labels {
31 kSecurityVersionLabel = -70005,
34 kOwnerManifestMeasurmentLabel = -71006,
40 enum open_dice_mode_value {
45 enum payload_entry_sizes {
47 kProfileNameLength = 10,
49 kIssuerSubjectKeyIdLength = kHmacDigestNumBytes,
53 kIssuerSubjectNameLength = 40,
55 kConfigDescBuffSize = 64,
57 static_assert(kIssuerSubjectNameLength <= kIssuerSubjectKeyIdLength * 2,
58 "Insufficient SubjectNameLength");
61 static uint8_t config_desc_buf[kConfigDescBuffSize] = {0};
63 const uint8_t kCborMap0[] = {0xa0};
65 static uint8_t cose_key_buffer[kCwtCoseKeyMaxVariableSizeBytes] = {0};
69 #define CWT_PROFILE_NAME "android.16"
71 static uint8_t get_chip_mode_cdi0(
void) {
72 return (lifecycle_is_prod() ? kDiceModeNormal : kDiceModeDebug);
75 static uint8_t get_chip_mode_cdi1(owner_app_domain_t key_domain) {
76 if (launder32(key_domain) != kOwnerAppDomainProd) {
77 return kDiceModeDebug;
80 return kDiceModeNormal;
83 static char issuer[kIssuerSubjectNameLength + 1] = {0};
84 static char subject[kIssuerSubjectNameLength + 1] = {0};
86 static void fill_dice_id_string(
87 const uint8_t dice_id[kIssuerSubjectKeyIdLength],
88 char dice_id_str[kIssuerSubjectNameLength + 1]) {
90 for (idx = 0; idx * 2 < kIssuerSubjectNameLength; idx++, dice_id_str += 2)
91 util_hexdump_byte(dice_id[idx], (uint8_t *)&dice_id_str[0]);
94 static rom_error_t configuration_descriptor_build(
95 size_t *buf_size,
const size_t sec_version,
98 cbor_out_init(&
cbor_out, config_desc_buf);
101 const size_t ptrs_len =
sizeof(ptrs) /
sizeof(ptrs[0]);
103 for (
size_t i = 0; i < ptrs_len; ++i) {
107 sz += cbor_write_map_header(cbor, (manifest_measurement != NULL) ? 2 : 1);
108 sz += cbor_write_int(cbor, kSecurityVersionLabel);
109 sz += cbor_write_int(cbor, sec_version);
111 if (manifest_measurement != NULL) {
112 sz += cbor_write_int(cbor, kOwnerManifestMeasurmentLabel);
113 sz += cbor_write_bstr(cbor, (uint8_t *)&manifest_measurement->digest[0],
114 kHmacDigestNumBytes);
118 return kErrorCertInvalidSize;
121 *buf_size = cbor_out_size(&
cbor_out);
126 rom_error_t dice_uds_tbs_cert_build(
132 uint8_t *tbs_cert,
size_t *tbs_cert_size) {
133 cwt_cose_key_values_t cwt_cose_key_params = {
134 .pub_key_ec_x = (uint8_t *)uds_pubkey->
x,
135 .pub_key_ec_x_size =
sizeof(uds_pubkey->
x),
136 .pub_key_ec_y = (uint8_t *)uds_pubkey->
y,
137 .pub_key_ec_y_size =
sizeof(uds_pubkey->
y),
145 OT_DISCARD(otp_rot_creator_auth_codesign_measurement);
146 OT_DISCARD(otp_rot_creator_auth_state_measurement);
148 HARDENED_RETURN_IF_ERROR(
149 cwt_cose_key_build(&cwt_cose_key_params, tbs_cert, tbs_cert_size));
154 rom_error_t dice_cdi_0_cert_build(
hmac_digest_t *rom_ext_measurement,
155 uint32_t rom_ext_security_version,
158 uint8_t *cert,
size_t *cert_size) {
160 size_t cose_key_size =
sizeof(cose_key_buffer);
161 cwt_cose_key_values_t cwt_cose_key_params = {
162 .pub_key_ec_x = (uint8_t *)cdi_0_pubkey->
x,
163 .pub_key_ec_x_size =
sizeof(cdi_0_pubkey->
x),
164 .pub_key_ec_y = (uint8_t *)cdi_0_pubkey->
y,
165 .pub_key_ec_y_size =
sizeof(cdi_0_pubkey->
y),
167 HARDENED_RETURN_IF_ERROR(cwt_cose_key_build(
168 &cwt_cose_key_params, &cose_key_buffer[0], &cose_key_size));
171 fill_dice_id_string((uint8_t *)(key_ids->
endorsement->digest), issuer);
172 fill_dice_id_string((uint8_t *)(key_ids->
cert->digest), subject);
175 cdi0_entry_payload_buffer[kCwtDiceChainEntryPayloadMaxVariableSizeBytes];
176 size_t cdi0_entry_payload_size =
sizeof(cdi0_entry_payload_buffer);
178 size_t config_desc_buf_size = kConfigDescBuffSize;
181 HARDENED_RETURN_IF_ERROR(configuration_descriptor_build(
182 &config_desc_buf_size, rom_ext_security_version, NULL));
184 hmac_sha256(config_desc_buf, config_desc_buf_size, &conf_hash);
185 util_reverse_bytes(conf_hash.digest, kHmacDigestNumBytes);
190 hmac_sha256(kCborMap0,
sizeof(kCborMap0), &auth_hash);
191 util_reverse_bytes(auth_hash.digest, kHmacDigestNumBytes);
193 uint8_t mode = get_chip_mode_cdi0();
194 cwt_dice_chain_entry_payload_values_t cwt_dice_chain_entry_payload_params = {
195 .auth_hash = (uint8_t *)&auth_hash.digest[0],
196 .auth_hash_size = kHmacDigestNumBytes,
197 .code_hash = (uint8_t *)&rom_ext_measurement->digest[0],
198 .code_hash_size = kHmacDigestNumBytes,
199 .subject = &subject[0],
200 .subject_size = kIssuerSubjectNameLength,
202 .mode_size =
sizeof(mode),
203 .issuer = &issuer[0],
204 .issuer_size = kIssuerSubjectNameLength,
205 .subject_pk = &cose_key_buffer[0],
206 .subject_pk_size = cose_key_size,
207 .config_desc = config_desc_buf,
208 .config_desc_size = config_desc_buf_size,
209 .config_hash = (uint8_t *)&conf_hash.digest[0],
210 .config_hash_size = kHmacDigestNumBytes,
211 .profile_name = CWT_PROFILE_NAME,
212 .profile_name_size = kProfileNameLength};
213 HARDENED_RETURN_IF_ERROR(cwt_dice_chain_entry_payload_build(
214 &cwt_dice_chain_entry_payload_params, cdi0_entry_payload_buffer,
215 &cdi0_entry_payload_size));
218 size_t cdi0_entry_input_size = kCwtDiceChainEntryInputMaxVariableSizeBytes;
219 if (cdi0_entry_input_size > *cert_size)
220 return kErrorCertInvalidSize;
221 cwt_dice_chain_entry_input_values_t cwt_dice_chain_entry_input_params = {
222 .payload = cdi0_entry_payload_buffer,
223 .payload_size = cdi0_entry_payload_size};
224 HARDENED_RETURN_IF_ERROR(cwt_dice_chain_entry_input_build(
225 &cwt_dice_chain_entry_input_params, cert, &cdi0_entry_input_size));
229 hmac_sha256(cert, cdi0_entry_input_size, &tbs_digest);
230 HARDENED_RETURN_IF_ERROR(
231 otbn_boot_attestation_endorse(&tbs_digest, &curr_tbs_signature));
232 util_p256_signature_le_to_be_convert(curr_tbs_signature.r,
233 curr_tbs_signature.s);
236 cwt_dice_chain_entry_values_t cwt_dice_chain_entry_params = {
237 .payload = cdi0_entry_payload_buffer,
238 .payload_size = cdi0_entry_payload_size,
239 .signature = (uint8_t *)&curr_tbs_signature,
241 HARDENED_RETURN_IF_ERROR(cwt_dice_chain_entry_build(
242 &cwt_dice_chain_entry_params, cert, cert_size));
245 HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_key_save(
251 rom_error_t dice_cdi_1_cert_build(
hmac_digest_t *owner_measurement,
253 uint32_t owner_security_version,
254 owner_app_domain_t key_domain,
257 uint8_t *cert,
size_t *cert_size) {
259 size_t cose_key_size =
sizeof(cose_key_buffer);
260 cwt_cose_key_values_t cwt_cose_key_params = {
261 .pub_key_ec_x = (uint8_t *)cdi_1_pubkey->
x,
262 .pub_key_ec_x_size =
sizeof(cdi_1_pubkey->
x),
263 .pub_key_ec_y = (uint8_t *)cdi_1_pubkey->
y,
264 .pub_key_ec_y_size =
sizeof(cdi_1_pubkey->
y),
266 HARDENED_RETURN_IF_ERROR(cwt_cose_key_build(
267 &cwt_cose_key_params, &cose_key_buffer[0], &cose_key_size));
270 fill_dice_id_string((uint8_t *)(key_ids->
endorsement->digest), issuer);
271 fill_dice_id_string((uint8_t *)(key_ids->
cert->digest), subject);
274 cdi1_entry_payload_buffer[kCwtDiceChainEntryPayloadMaxVariableSizeBytes];
275 size_t cdi1_entry_payload_size =
sizeof(cdi1_entry_payload_buffer);
277 size_t config_desc_buf_size =
sizeof(config_desc_buf);
278 HARDENED_RETURN_IF_ERROR(configuration_descriptor_build(
279 &config_desc_buf_size, owner_security_version,
280 owner_manifest_measurement));
282 hmac_sha256(config_desc_buf, config_desc_buf_size, &conf_hash);
283 util_reverse_bytes(conf_hash.digest, kHmacDigestNumBytes);
288 hmac_sha256(kCborMap0,
sizeof(kCborMap0), &auth_hash);
289 util_reverse_bytes(auth_hash.digest, kHmacDigestNumBytes);
291 uint8_t mode = get_chip_mode_cdi1(key_domain);
292 cwt_dice_chain_entry_payload_values_t cwt_dice_chain_entry_payload_params = {
293 .auth_hash = (uint8_t *)&auth_hash.digest[0],
294 .auth_hash_size = kHmacDigestNumBytes,
295 .code_hash = (uint8_t *)&owner_measurement->digest[0],
296 .code_hash_size = kHmacDigestNumBytes,
297 .subject = &subject[0],
298 .subject_size = kIssuerSubjectNameLength,
300 .mode_size =
sizeof(mode),
301 .issuer = &issuer[0],
302 .issuer_size = kIssuerSubjectNameLength,
303 .subject_pk = &cose_key_buffer[0],
304 .subject_pk_size = cose_key_size,
305 .config_desc = config_desc_buf,
306 .config_desc_size = config_desc_buf_size,
307 .config_hash = (uint8_t *)&conf_hash.digest[0],
308 .config_hash_size = kHmacDigestNumBytes,
309 .profile_name = CWT_PROFILE_NAME,
310 .profile_name_size = kProfileNameLength};
311 HARDENED_RETURN_IF_ERROR(cwt_dice_chain_entry_payload_build(
312 &cwt_dice_chain_entry_payload_params, cdi1_entry_payload_buffer,
313 &cdi1_entry_payload_size));
316 size_t cdi1_entry_input_size = kCwtDiceChainEntryInputMaxVariableSizeBytes;
317 if (cdi1_entry_input_size > *cert_size)
318 return kErrorCertInvalidSize;
319 cwt_dice_chain_entry_input_values_t cwt_dice_chain_entry_input_params = {
320 .payload = cdi1_entry_payload_buffer,
321 .payload_size = cdi1_entry_payload_size};
322 HARDENED_RETURN_IF_ERROR(cwt_dice_chain_entry_input_build(
323 &cwt_dice_chain_entry_input_params, cert, &cdi1_entry_input_size));
327 hmac_sha256(cert, cdi1_entry_input_size, &tbs_digest);
328 HARDENED_RETURN_IF_ERROR(
329 otbn_boot_attestation_endorse(&tbs_digest, &curr_tbs_signature));
330 util_p256_signature_le_to_be_convert(curr_tbs_signature.r,
331 curr_tbs_signature.s);
334 cwt_dice_chain_entry_values_t cwt_dice_chain_entry_params = {
335 .payload = cdi1_entry_payload_buffer,
336 .payload_size = cdi1_entry_payload_size,
337 .signature = (uint8_t *)&curr_tbs_signature,
339 HARDENED_RETURN_IF_ERROR(cwt_dice_chain_entry_build(
340 &cwt_dice_chain_entry_params, cert, cert_size));
343 HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_key_save(