Software APIs
rom_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 "sw/device/silicon_creator/rom_ext/rom_ext.h"
6 
13 #include "sw/device/silicon_creator/lib/base/boot_measurements.h"
16 #include "sw/device/silicon_creator/lib/boot_data.h"
17 #include "sw/device/silicon_creator/lib/boot_log.h"
18 #include "sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.h"
19 #include "sw/device/silicon_creator/lib/boot_svc/boot_svc_header.h"
20 #include "sw/device/silicon_creator/lib/boot_svc/boot_svc_msg.h"
21 #include "sw/device/silicon_creator/lib/cert/dice_chain.h"
22 #include "sw/device/silicon_creator/lib/dbg_print.h"
23 #include "sw/device/silicon_creator/lib/drivers/ast.h"
24 #include "sw/device/silicon_creator/lib/drivers/epmp.h"
25 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
26 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
27 #include "sw/device/silicon_creator/lib/drivers/ibex.h"
28 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
29 #include "sw/device/silicon_creator/lib/drivers/otp.h"
30 #include "sw/device/silicon_creator/lib/drivers/pinmux.h"
31 #include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
32 #include "sw/device/silicon_creator/lib/drivers/rnd.h"
33 #include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
34 #include "sw/device/silicon_creator/lib/drivers/uart.h"
35 #include "sw/device/silicon_creator/lib/epmp_state.h"
36 #include "sw/device/silicon_creator/lib/manifest.h"
37 #include "sw/device/silicon_creator/lib/manifest_def.h"
38 #include "sw/device/silicon_creator/lib/ownership/ownership.h"
39 #include "sw/device/silicon_creator/lib/ownership/ownership_activate.h"
40 #include "sw/device/silicon_creator/lib/ownership/ownership_key.h"
41 #include "sw/device/silicon_creator/lib/ownership/ownership_unlock.h"
42 #include "sw/device/silicon_creator/lib/shutdown.h"
43 #include "sw/device/silicon_creator/lib/sigverify/ecdsa_p256_key.h"
44 #include "sw/device/silicon_creator/lib/sigverify/rsa_verify.h"
45 #include "sw/device/silicon_creator/lib/sigverify/sigverify.h"
46 #include "sw/device/silicon_creator/rom_ext/rescue.h"
47 #include "sw/device/silicon_creator/rom_ext/rom_ext_boot_policy.h"
48 #include "sw/device/silicon_creator/rom_ext/rom_ext_boot_policy_ptrs.h"
49 #include "sw/device/silicon_creator/rom_ext/rom_ext_manifest.h"
50 #include "sw/device/silicon_creator/rom_ext/sigverify_keys.h"
51 
52 #include "flash_ctrl_regs.h" // Generated.
53 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" // Generated.
54 #include "otp_ctrl_regs.h" // Generated.
55 #include "sram_ctrl_regs.h" // Generated.
56 
57 // Declaration for the ROM_EXT manifest start address, populated by the linker
58 extern char _rom_ext_start_address[];
59 // Declaration for the chip_info structure stored in ROM.
60 extern const char _rom_chip_info_start[];
61 
62 // Life cycle state of the chip.
63 lifecycle_state_t lc_state;
64 
65 // Owner configuration details parsed from the onwer info pages.
67 
68 // Owner application keys.
70 
71 // Verifying key index
72 size_t verify_key;
73 
75 static rom_error_t rom_ext_irq_error(void) {
76  uint32_t mcause;
77  CSR_READ(CSR_REG_MCAUSE, &mcause);
78 
79  // TODO(opentitan#22947): Remove this debug print prior to a formal release.
80  uint32_t mepc, mtval;
81  CSR_READ(CSR_REG_MEPC, &mepc);
82  CSR_READ(CSR_REG_MTVAL, &mtval);
83  dbg_printf("MCAUSE=%x MEPC=%x MTVAL=%x\r\n", mcause, mepc, mtval);
84 
85  // Shuffle the mcause bits into the uppermost byte of the word and report
86  // the cause as kErrorRomExtInterrupt.
87  // Based on the ibex verilog, it appears that the most significant bit
88  // indicates whether the cause is an exception (0) or external interrupt (1),
89  // and the 5 least significant bits indicate which exception/interrupt.
90  //
91  // Preserve the MSB and shift the 7 LSBs into the upper byte.
92  // (we preserve 7 instead of 5 because the verilog hardcodes the unused bits
93  // as zero and those would be the next bits used should the number of
94  // interrupt causes increase).
95  mcause = (mcause & 0x80000000) | ((mcause & 0x7f) << 24);
96  return kErrorRomExtInterrupt + mcause;
97 }
98 
100 static uint32_t rom_ext_current_slot(void) {
101  uint32_t pc = ibex_addr_remap_get(0);
102  if (pc == 0) {
103  // If the remap window has address zero, we're running from flash and we can
104  // simply read the program counter.
105  asm("auipc %[pc], 0;" : [pc] "=r"(pc));
106  }
107 
108  const uint32_t kFlashSlotA = TOP_EARLGREY_FLASH_CTRL_MEM_BASE_ADDR;
109  const uint32_t kFlashSlotB =
110  kFlashSlotA + TOP_EARLGREY_FLASH_CTRL_MEM_SIZE_BYTES / 2;
111  const uint32_t kFlashSlotEnd =
113  uint32_t side = 0;
114  if (pc >= kFlashSlotA && pc < kFlashSlotB) {
115  // Running in Slot A.
116  side = kBootSlotA;
117  } else if (pc >= kFlashSlotB && pc < kFlashSlotEnd) {
118  // Running in Slot B.
119  side = kBootSlotB;
120  } else {
121  // Not running in flash: impossible.
122  HARDENED_TRAP();
123  }
124  return side;
125 }
126 
127 void rom_ext_check_rom_expectations(void) {
128  // Check the ePMP state.
129  SHUTDOWN_IF_ERROR(epmp_state_check());
130  // Check sec_mmio expectations.
131  // We don't check the counters since we don't want to tie ROM_EXT to a
132  // specific ROM version.
133  sec_mmio_check_values(rnd_uint32());
134 }
135 
137 static rom_error_t rom_ext_init(boot_data_t *boot_data) {
139  lc_state = lifecycle_state_get();
140  pinmux_init();
141  // Configure UART0 as stdout.
142  uart_init(kUartNCOValue);
143 
144  // Reclaim entries 0 ~ 7 from ROM and ROM_EXT IMM_SECTION.
145  for (int8_t i = 7; i >= 0; --i) {
146  epmp_clear((uint8_t)i);
147  }
148  HARDENED_RETURN_IF_ERROR(epmp_state_check());
149 
150  // Conditionally patch AST and check that it is in the expected state.
151  HARDENED_RETURN_IF_ERROR(ast_patch(lc_state));
152 
153  // Check that the retention RAM is initialized.
154  // TODO(lowrisc#22387): Check if return-if-error here is a potential
155  // boot-loop.
156  HARDENED_RETURN_IF_ERROR(retention_sram_check_version());
157 
158  // Get the boot_data record
159  HARDENED_RETURN_IF_ERROR(boot_data_read(lc_state, boot_data));
160 
161  return kErrorOk;
162 }
163 
164 void rom_ext_sram_exec(owner_sram_exec_mode_t mode) {
165  switch (mode) {
166  case kOwnerSramExecModeEnabled:
167  // In enabled mode, we do not lock the register so owner code can disable
168  // SRAM exec at some later time.
169  HARDENED_CHECK_EQ(mode, kOwnerSramExecModeEnabled);
171  SRAM_CTRL_EXEC_REG_OFFSET,
172  kMultiBitBool4True);
173  break;
174  case kOwnerSramExecModeDisabled:
175  // In disabled mode, we do not lock the register so owner code can enable
176  // SRAM exec at some later time.
177  HARDENED_CHECK_EQ(mode, kOwnerSramExecModeDisabled);
179  SRAM_CTRL_EXEC_REG_OFFSET,
180  kMultiBitBool4False);
181  break;
182  case kOwnerSramExecModeDisabledLocked:
183  default:
184  // In disabled locked mode, we lock the register so the mode cannot be
185  // changed.
187  SRAM_CTRL_EXEC_REG_OFFSET,
188  kMultiBitBool4False);
190  SRAM_CTRL_EXEC_REGWEN_REG_OFFSET,
191  0);
192  break;
193  }
194 }
195 
197 static rom_error_t rom_ext_verify(const manifest_t *manifest,
198  const boot_data_t *boot_data) {
199  RETURN_IF_ERROR(rom_ext_boot_policy_manifest_check(manifest, boot_data));
200  ownership_key_alg_t key_alg = kOwnershipKeyAlgEcdsaP256;
201  RETURN_IF_ERROR(owner_keyring_find_key(
202  &keyring, key_alg,
203  sigverify_ecdsa_p256_key_id_get(&manifest->ecdsa_public_key),
204  &verify_key));
205 
206  dbg_printf("app_verify: key=%u alg=%C domain=%C\r\n", verify_key,
207  keyring.key[verify_key]->key_alg,
208  keyring.key[verify_key]->key_domain);
209 
210  memset(boot_measurements.bl0.data, (int)rnd_uint32(),
211  sizeof(boot_measurements.bl0.data));
212 
213  hmac_sha256_init();
214  // Hash usage constraints.
215  manifest_usage_constraints_t usage_constraints_from_hw;
216  sigverify_usage_constraints_get(manifest->usage_constraints.selector_bits |
217  keyring.key[verify_key]->usage_constraint,
218  &usage_constraints_from_hw);
219  hmac_sha256_update(&usage_constraints_from_hw,
220  sizeof(usage_constraints_from_hw));
221  // Hash the remaining part of the image.
222  manifest_digest_region_t digest_region = manifest_digest_region_get(manifest);
223  hmac_sha256_update(digest_region.start, digest_region.length);
224  // TODO(#19596): add owner configuration block to measurement.
225  // Verify signature
226  hmac_sha256_process();
227  hmac_digest_t act_digest;
228  hmac_sha256_final(&act_digest);
229 
230  static_assert(sizeof(boot_measurements.bl0) == sizeof(act_digest),
231  "Unexpected BL0 digest size.");
232  memcpy(&boot_measurements.bl0, &act_digest, sizeof(boot_measurements.bl0));
233 
234  uint32_t flash_exec = 0;
235  return sigverify_ecdsa_p256_verify(&manifest->ecdsa_signature,
236  &keyring.key[verify_key]->data.ecdsa,
237  &act_digest, &flash_exec);
238 }
239 
240 /**
241  * These symbols are defined in
242  * `opentitan/sw/device/silicon_creator/rom_ext/rom_ext.ld`, and describe the
243  * location of the flash header.
244  */
245 extern char _owner_virtual_start_address[];
246 extern char _owner_virtual_size[];
247 
248 /**
249  * Compute the virtual address corresponding to the physical address `lma_addr`.
250  *
251  * @param manifest Pointer to the current manifest.
252  * @param lma_addr Load address or physical address.
253  * @return the computed virtual address.
254  */
256 static uintptr_t owner_vma_get(const manifest_t *manifest, uintptr_t lma_addr) {
257  return (lma_addr - (uintptr_t)manifest +
258  (uintptr_t)_owner_virtual_start_address + CHIP_ROM_EXT_SIZE_MAX);
259 }
260 
262 static rom_error_t rom_ext_boot(boot_data_t *boot_data, boot_log_t *boot_log,
263  const manifest_t *manifest) {
264  // Determine which owner block the key came from and measure that block.
265  hmac_digest_t owner_measurement;
266  const owner_application_key_t *key = keyring.key[verify_key];
267  owner_block_measurement(owner_block_key_page(key), &owner_measurement);
268 
269  keymgr_binding_value_t sealing_binding;
270  if (boot_data->ownership_state == kOwnershipStateLockedOwner) {
271  HARDENED_CHECK_EQ(boot_data->ownership_state, kOwnershipStateLockedOwner);
272  // If we're in LockedOwner, initialize the sealing binding with the
273  // diversification constant associated with key applicaiton key that
274  // validated the owner firmware payload.
275  static_assert(
276  sizeof(key->raw_diversifier) == sizeof(keymgr_binding_value_t),
277  "Expect the keymgr binding value to be the same size as an application "
278  "key diversifier");
279  memcpy(&sealing_binding, key->raw_diversifier, sizeof(sealing_binding));
280  } else {
281  // If we're not in LockedOwner state, we don't want to derive any valid
282  // sealing keys, so set the binding constant to a nonsense value.
283  memset(&sealing_binding, 0x55, sizeof(sealing_binding));
284  }
285 
286  // Generate CDI_1 attestation keys and certificate.
287  HARDENED_RETURN_IF_ERROR(dice_chain_attestation_owner(
288  manifest, &boot_measurements.bl0, &owner_measurement, &sealing_binding,
289  key->key_domain));
290 
291  // Write the DICE certs to flash if they have been updated.
292  HARDENED_RETURN_IF_ERROR(dice_chain_flush_flash());
293 
294  // Remove write and erase access to the certificate pages before handing over
295  // execution to the owner firmware (owner firmware can still read).
296  flash_ctrl_cert_info_page_owner_restrict(&kFlashCtrlInfoPageDiceCerts);
297 
298  // Disable access to silicon creator info pages, the OTP creator partition
299  // and the OTP direct access interface until the next reset.
300  flash_ctrl_creator_info_pages_lockdown();
301  otp_creator_sw_cfg_lockdown();
302  SEC_MMIO_WRITE_INCREMENT(kFlashCtrlSecMmioCreatorInfoPagesLockdown +
303  kOtpSecMmioCreatorSwCfgLockDown);
304 
305  epmp_clear_lock_bits();
306 
307  HARDENED_RETURN_IF_ERROR(epmp_state_check());
308 
309  // Configure address translation, compute the epmp regions and the entry
310  // point for the virtual address in case the address translation is enabled.
311  // Otherwise, compute the epmp regions and the entry point for the load
312  // address.
313  //
314  // We'll map the owner code TOR region as ePMP entries 2/3. If using address
315  // translation, we'll configure ePMP entry 4 as the read-only region.
316  epmp_region_t text_region = manifest_code_region_get(manifest);
317  uintptr_t entry_point = manifest_entry_point_get(manifest);
318  switch (launder32(manifest->address_translation)) {
319  case kHardenedBoolTrue:
321  ibex_addr_remap_1_set((uintptr_t)_owner_virtual_start_address,
322  (uintptr_t)manifest, (size_t)_owner_virtual_size);
323  SEC_MMIO_WRITE_INCREMENT(kAddressTranslationSecMmioConfigure);
324 
325  // Unlock read-only for the whole rom_ext virtual memory.
326  HARDENED_RETURN_IF_ERROR(epmp_state_check());
327  epmp_set_napot(
328  4,
329  (epmp_region_t){.start = (uintptr_t)_owner_virtual_start_address,
330  .end = (uintptr_t)_owner_virtual_start_address +
331  (uintptr_t)_owner_virtual_size},
332  kEpmpPermReadOnly);
333  HARDENED_RETURN_IF_ERROR(epmp_state_check());
334 
335  // Move the ROM_EXT execution section from the load address to the virtual
336  // address.
337  // TODO(#13513): Harden these calculations.
338  text_region.start = owner_vma_get(manifest, text_region.start);
339  text_region.end = owner_vma_get(manifest, text_region.end);
340  entry_point = owner_vma_get(manifest, entry_point);
341  break;
342  case kHardenedBoolFalse:
344  // Normally we'd want to clear the ROM region since we aren't using it
345  // anymore and since it isn't being used to encode access to the virtual
346  // window. However, for SiVal, we want to keep low entries locked to
347  // prevent using low entries to override policy in higher entries.
348  // epmp_clear_rom_region();
349  break;
350  default:
351  HARDENED_TRAP();
352  }
353 
354  // Allow execution of owner stage executable code (text) sections,
355  // unlock the ROM_EXT code regions so the next stage can re-use those
356  // entries and clear RLB to prevent further changes to locked ePMP regions.
357  HARDENED_RETURN_IF_ERROR(epmp_state_check());
358  epmp_set_tor(2, text_region, kEpmpPermReadExecute);
359 
360  // Now that we're done reconfiguring the ePMP, we'll clear the RLB bit to
361  // prevent any modification to locked entries.
362  epmp_clear_rlb();
363  HARDENED_RETURN_IF_ERROR(epmp_state_check());
364 
365  // Lock the address translation windows.
366  ibex_addr_remap_lockdown(0);
367  ibex_addr_remap_lockdown(1);
368 
369  // Lock the flash according to the ownership configuration.
370  HARDENED_RETURN_IF_ERROR(
371  ownership_flash_lockdown(boot_data, boot_log->bl0_slot, &owner_config));
372 
373  dbg_print_epmp();
374 
375  // Verify expectations before jumping to owner code.
376  // TODO: we really want to call rnd_uint32 here to select a random starting
377  // location for checking expectations. However, rnd_uint32 read from OTP
378  // to know if it's allowed to used the CSRNG and OTP is locked down.
379  sec_mmio_check_values_except_otp(/*rnd_uint32()*/ 0,
381  // Jump to OWNER entry point.
382  dbg_printf("entry: 0x%x\r\n", (unsigned int)entry_point);
383  ((owner_stage_entry_point *)entry_point)();
384 
385  return kErrorRomExtBootFailed;
386 }
387 
389 static rom_error_t boot_svc_next_boot_bl0_slot_handler(
391  boot_log_t *boot_log) {
392  uint32_t active_slot = boot_data->primary_bl0_slot;
393  uint32_t primary_slot = boot_svc_msg->next_boot_bl0_slot_req.primary_bl0_slot;
394  rom_error_t error = kErrorOk;
395 
396  // If the requested primary slot is the same as the active slot, this request
397  // is a no-op.
398  if (active_slot != primary_slot) {
399  switch (primary_slot) {
400  case kBootSlotA:
401  case kBootSlotB:
402  boot_data->primary_bl0_slot = primary_slot;
403  // Write boot data, updating relevant fields and recomputing the digest.
404  HARDENED_RETURN_IF_ERROR(boot_data_write(boot_data));
405  // Read the boot data back to ensure the correct slot is booted this
406  // time.
407  HARDENED_RETURN_IF_ERROR(boot_data_read(lc_state, boot_data));
408  // Update the boot log.
410  break;
411  case kBootSlotUnspecified:
412  // Do nothing.
413  break;
414  default:
415  error = kErrorBootSvcBadSlot;
416  }
417  }
418 
419  // Record the new primary slot for use in the response message.
420  active_slot = boot_data->primary_bl0_slot;
421 
422  uint32_t next_slot = boot_svc_msg->next_boot_bl0_slot_req.next_bl0_slot;
423  switch (launder32(next_slot)) {
424  case kBootSlotA:
425  case kBootSlotB:
426  // We overwrite the RAM copy of the primary slot to the requested next
427  // slot. This will cause a one-time boot of the requested side.
428  boot_data->primary_bl0_slot = next_slot;
429  break;
430  case kBootSlotUnspecified:
431  // Do nothing.
432  break;
433  default:
434  error = kErrorBootSvcBadSlot;
435  }
436 
437  boot_svc_next_boot_bl0_slot_res_init(error, active_slot,
438  &boot_svc_msg->next_boot_bl0_slot_res);
439  // We always return OK here because we've logged any error status in the boot
440  // services response message and we want the boot flow to continue.
441  return kErrorOk;
442 }
443 
445 static rom_error_t boot_svc_min_sec_ver_handler(boot_svc_msg_t *boot_svc_msg,
447  const uint32_t current_min_sec_ver = boot_data->min_security_version_bl0;
448  const uint32_t requested_min_sec_ver =
449  boot_svc_msg->next_boot_bl0_slot_req.next_bl0_slot;
450 
451  // Ensure the requested minimum security version isn't lower than the current
452  // minimum security version.
453  if (launder32(requested_min_sec_ver) > current_min_sec_ver) {
454  HARDENED_CHECK_GT(requested_min_sec_ver, current_min_sec_ver);
455  uint32_t max_sec_ver = current_min_sec_ver;
456 
457  // Check the two flash slots for valid manifests and determine the maximum
458  // value of the new minimum_security_version. This prevents a malicious
459  // MinBl0SecVer request from making the chip un-bootable.
460  const manifest_t *manifest = rom_ext_boot_policy_manifest_a_get();
461  rom_error_t error = rom_ext_verify(manifest, boot_data);
462  if (error == kErrorOk && manifest->security_version > max_sec_ver) {
463  max_sec_ver = manifest->security_version;
464  }
465  manifest = rom_ext_boot_policy_manifest_b_get();
466  error = rom_ext_verify(manifest, boot_data);
467  if (error == kErrorOk && manifest->security_version > max_sec_ver) {
468  max_sec_ver = manifest->security_version;
469  }
470 
471  if (requested_min_sec_ver <= max_sec_ver) {
472  HARDENED_CHECK_LE(requested_min_sec_ver, max_sec_ver);
473  // Update boot data to the requested minimum BL0 security version.
474  boot_data->min_security_version_bl0 = requested_min_sec_ver;
475 
476  // Write boot data, updating relevant fields and recomputing the digest.
477  HARDENED_RETURN_IF_ERROR(boot_data_write(boot_data));
478  // Read the boot data back to ensure the correct policy is used this boot.
479  HARDENED_RETURN_IF_ERROR(boot_data_read(lc_state, boot_data));
480 
481  boot_svc_min_bl0_sec_ver_res_init(boot_data->min_security_version_bl0,
482  kErrorOk,
483  &boot_svc_msg->min_bl0_sec_ver_res);
484 
485  HARDENED_CHECK_EQ(requested_min_sec_ver,
487  return kErrorOk;
488  }
489  }
490  boot_svc_min_bl0_sec_ver_res_init(current_min_sec_ver, kErrorBootSvcBadSecVer,
491  &boot_svc_msg->min_bl0_sec_ver_res);
492  return kErrorOk;
493 }
494 
496 static rom_error_t handle_boot_svc(boot_data_t *boot_data,
497  boot_log_t *boot_log) {
498  boot_svc_msg_t *boot_svc_msg = &retention_sram_get()->creator.boot_svc_msg;
499  // TODO(lowRISC#22387): Examine the boot_svc code paths for boot loops.
500  if (boot_svc_msg->header.identifier == kBootSvcIdentifier) {
501  HARDENED_RETURN_IF_ERROR(boot_svc_header_check(&boot_svc_msg->header));
502  uint32_t msg_type = boot_svc_msg->header.type;
503  switch (launder32(msg_type)) {
504  case kBootSvcEmptyReqType:
505  HARDENED_CHECK_EQ(msg_type, kBootSvcEmptyReqType);
506  boot_svc_empty_res_init(&boot_svc_msg->empty);
507  break;
508  case kBootSvcNextBl0SlotReqType:
509  HARDENED_CHECK_EQ(msg_type, kBootSvcNextBl0SlotReqType);
510  return boot_svc_next_boot_bl0_slot_handler(boot_svc_msg, boot_data,
511  boot_log);
512  case kBootSvcMinBl0SecVerReqType:
513  HARDENED_CHECK_EQ(msg_type, kBootSvcMinBl0SecVerReqType);
514  return boot_svc_min_sec_ver_handler(boot_svc_msg, boot_data);
515  case kBootSvcOwnershipUnlockReqType:
516  HARDENED_CHECK_EQ(msg_type, kBootSvcOwnershipUnlockReqType);
517  return ownership_unlock_handler(boot_svc_msg, boot_data);
518  case kBootSvcOwnershipActivateReqType:
519  HARDENED_CHECK_EQ(msg_type, kBootSvcOwnershipActivateReqType);
520  return ownership_activate_handler(boot_svc_msg, boot_data);
521  case kBootSvcEmptyResType:
522  case kBootSvcNextBl0SlotResType:
523  case kBootSvcMinBl0SecVerResType:
524  case kBootSvcOwnershipUnlockResType:
525  case kBootSvcOwnershipActivateResType:
526  // For response messages left in ret-ram we do nothing.
527  break;
528  default:
529  // For messages with an unknown msg_type, we do nothing.
530  ;
531  }
532  }
533  return kErrorOk;
534 }
535 
537 static rom_error_t rom_ext_try_next_stage(boot_data_t *boot_data,
538  boot_log_t *boot_log) {
540  rom_ext_boot_policy_manifests_get(boot_data);
541  rom_error_t error = kErrorRomExtBootFailed;
542  rom_error_t slot[2] = {0, 0};
543  for (size_t i = 0; i < ARRAYSIZE(manifests.ordered); ++i) {
544  error = rom_ext_verify(manifests.ordered[i], boot_data);
545  slot[i] = error;
546  if (error != kErrorOk) {
547  continue;
548  }
549 
550  if (manifests.ordered[i] == rom_ext_boot_policy_manifest_a_get()) {
551  boot_log->bl0_slot = kBootSlotA;
552  } else if (manifests.ordered[i] == rom_ext_boot_policy_manifest_b_get()) {
553  boot_log->bl0_slot = kBootSlotB;
554  } else {
555  return kErrorRomExtBootFailed;
556  }
557  boot_log_digest_update(boot_log);
558 
559  // Boot fails if a verified ROM_EXT cannot be booted.
560  RETURN_IF_ERROR(rom_ext_boot(boot_data, boot_log, manifests.ordered[i]));
561  // `rom_ext_boot()` should never return `kErrorOk`, but if it does
562  // we must shut down the chip instead of trying the next ROM_EXT.
563  return kErrorRomExtBootFailed;
564  }
565 
566  // If we get here, the loop exited after trying both slots.
567  // If we see kErrorBootPolicyBadIdentifier as the error, we probably have an
568  // empty slot. In that case, the "bad identifier" error is not helpful, so
569  // maybe choose the error from the other slot.
570  if (error == kErrorBootPolicyBadIdentifier && error == slot[1]) {
571  // If the bad identifier error comes from the non-primary slot, prefer
572  // the error from the primary slot.
573  error = slot[0];
574  }
575  return error;
576 }
577 
578 static rom_error_t rom_ext_start(boot_data_t *boot_data, boot_log_t *boot_log) {
579  HARDENED_RETURN_IF_ERROR(rom_ext_init(boot_data));
580  const manifest_t *self = rom_ext_manifest();
581  dbg_printf("Starting ROM_EXT %u.%u\r\n", self->version_major,
582  self->version_minor);
583 
584  uint32_t hash_enforcement =
585  otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN_OFFSET);
586  if (hash_enforcement != kHardenedBoolTrue) {
587  // CAUTION: The message below should match the message defined in:
588  // //sw/device/silicon_creator/rom_ext/imm_section/defs.bzl
589  dbg_printf("info: imm_section hash unenforced\r\n");
590  }
591 
592  // Prepare dice chain builder for CDI_1.
593  HARDENED_RETURN_IF_ERROR(dice_chain_init());
594 
595  // Initialize the boot_log in retention RAM.
596  const chip_info_t *rom_chip_info = (const chip_info_t *)_rom_chip_info_start;
597  boot_log_check_or_init(boot_log, rom_ext_current_slot(), rom_chip_info);
598  boot_log->rom_ext_major = self->version_major;
599  boot_log->rom_ext_minor = self->version_minor;
600  boot_log->rom_ext_size = CHIP_ROM_EXT_SIZE_MAX;
601  // Even though `primary_bl0_slot` can be changed by boot svc, we initialize
602  // it here so the "SetNextBl0" can do a one-time override of the RAM copy
603  // of `boot_data`.
605 
606  // Initialize the chip ownership state.
607  rom_error_t error;
608  error = ownership_init(boot_data, &owner_config, &keyring);
609  if (error == kErrorWriteBootdataThenReboot) {
610  return error;
611  }
612  // TODO(cfrantz): evaluate permissible ownership init failure conditions
613  // and change this to HARDENED_RETURN_IF_ERROR.
614  if (error != kErrorOk) {
615  dbg_printf("ownership_init: %x\r\n", error);
616  }
617 
618  // Configure SRAM execution as the owner requested.
619  rom_ext_sram_exec(owner_config.sram_exec);
620 
621  // Handle any pending boot_svc commands.
622  uint32_t reset_reasons = retention_sram_get()->creator.reset_reasons;
623  uint32_t skip_boot_svc = reset_reasons & (1 << kRstmgrReasonLowPowerExit);
624  if (skip_boot_svc == 0) {
625  error = handle_boot_svc(boot_data, boot_log);
626  if (error == kErrorWriteBootdataThenReboot) {
627  // Boot services reports errors by writing a status code into the reply
628  // messages. Regardless of whether a boot service request produced an
629  // error, we want to continue booting unless the error specifically asks
630  // for a reboot.
631  return error;
632  }
633  }
634 
635  // Synchronize the boot_log entries that could be changed by boot services.
641  boot_log_digest_update(boot_log);
642 
643  if (uart_break_detect(kRescueDetectTime) == kHardenedBoolTrue) {
644  dbg_printf("rescue: remember to clear break\r\n");
645  uart_enable_receiver();
646  ownership_pages_lockdown(boot_data, /*rescue=*/kHardenedBoolTrue);
647  // TODO: update rescue protocol to accept boot data and rescue
648  // config from the owner_config.
649  error = rescue_protocol(boot_data, owner_config.rescue);
650  } else {
651  ownership_pages_lockdown(boot_data, /*rescue=*/kHardenedBoolFalse);
652  error = rom_ext_try_next_stage(boot_data, boot_log);
653  }
654  return error;
655 }
656 
657 void rom_ext_main(void) {
658  rom_ext_check_rom_expectations();
660  boot_log_t *boot_log = &retention_sram_get()->creator.boot_log;
661 
662  rom_error_t error = rom_ext_start(&boot_data, boot_log);
663  if (error == kErrorWriteBootdataThenReboot) {
664  HARDENED_CHECK_EQ(error, kErrorWriteBootdataThenReboot);
665  error = boot_data_write(&boot_data);
666  }
667  shutdown_finalize(error);
668 }
669 
670 OT_USED
671 void rom_ext_interrupt_handler(void) { shutdown_finalize(rom_ext_irq_error()); }
672 
673 // We only need a single handler for all ROM_EXT interrupts, but we want to
674 // keep distinct symbols to make writing tests easier. In the ROM_EXT,
675 // alias all interrupt handler symbols to the single handler.
676 OT_USED
677 OT_ALIAS("rom_ext_interrupt_handler")
678 void rom_ext_exception_handler(void);
679 
680 OT_USED
681 OT_ALIAS("rom_ext_interrupt_handler")
682 void rom_ext_nmi_handler(void);