5 #include "sw/device/silicon_creator/lib/boot_data.h"
13 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
14 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
15 #include "sw/device/silicon_creator/lib/drivers/otp.h"
16 #include "sw/device/silicon_creator/lib/error.h"
18 #include "flash_ctrl_regs.h"
20 #include "otp_ctrl_regs.h"
22 static_assert(kBootDataValidEntry ==
23 ((uint64_t)kFlashCtrlErasedWord << 32 | kFlashCtrlErasedWord),
24 "kBootDataValidEntry words must be kFlashCtrlErasedWord");
25 static_assert(kBootDataEntriesPerPage ==
26 FLASH_CTRL_PARAM_BYTES_PER_PAGE /
sizeof(
boot_data_t),
27 "Number of boot data entries per page is incorrect");
28 static_assert(
sizeof(
boot_data_t) % FLASH_CTRL_PARAM_BYTES_PER_WORD == 0,
29 "Size of `boot_data_t` must be a multiple of flash word size.");
30 static_assert(!(FLASH_CTRL_PARAM_BYTES_PER_PAGE &
31 (FLASH_CTRL_PARAM_BYTES_PER_PAGE - 1)),
32 "Size of a flash page must be a power of two.");
34 "Size of `boot_data_t` must be a power of two.");
37 FLASH_CTRL_PARAM_BYTES_PER_WORD ==
39 "`is_valid` must be flash word aligned.");
51 &kFlashCtrlInfoPageBootData0,
52 &kFlashCtrlInfoPageBootData1,
65 static void boot_data_digest_compute(
const void *
boot_data,
68 kDigestRegionOffset =
sizeof((
boot_data_t){0}.digest),
69 kDigestRegionSize =
sizeof(
boot_data_t) - kDigestRegionOffset,
72 "`digest` must be the first field of `boot_data_t`.");
74 hmac_sha256((
const char *)
boot_data + kDigestRegionOffset, kDigestRegionSize,
86 static_assert(kFlashCtrlErasedWord == UINT32_MAX,
87 "kFlashCtrlErasedWord must be UINT32_MAX");
88 size_t i = 0, r = kBootDataNumWords - 1;
90 uint32_t res = kFlashCtrlErasedWord;
91 for (; launder32(i) < kBootDataNumWords && launder32(r) < kBootDataNumWords;
99 if (launder32(res) == kFlashCtrlErasedWord) {
123 size_t index, uint32_t *masked_identifier) {
124 static_assert(kBootDataValidEntry == UINT64_MAX,
125 "is_valid must be UINT64_MAX for valid entries.");
126 static_assert(kBootDataInvalidEntry == 0,
127 "is_valid must be 0 for invalid entries.");
131 kIdentifierOffset = offsetof(
boot_data_t, identifier),
134 kIdentifierOffset - kIsValidOffset ==
sizeof((
boot_data_t){0}.is_valid),
135 "is_valid and identifier must be consecutive.");
137 *masked_identifier = 0;
139 const uint32_t offset = index *
sizeof(
boot_data_t) + kIsValidOffset;
140 HARDENED_RETURN_IF_ERROR(flash_ctrl_info_read(page, offset, 3, buf));
141 *masked_identifier = buf[0] & buf[1] & buf[2];
156 const uint32_t offset = index *
sizeof(
boot_data_t);
157 return flash_ctrl_info_read(page, offset, kBootDataNumWords,
boot_data);
178 static rom_error_t boot_data_entry_write_impl(
187 RETURN_IF_ERROR(flash_ctrl_info_erase(page, kFlashCtrlEraseTypePage));
191 const uint32_t offset = index *
sizeof(
boot_data_t);
193 flash_ctrl_info_write(page, offset, kHmacDigestNumWords,
boot_data));
196 kSecondWriteOffsetBytes = offsetof(
boot_data_t, identifier),
197 kSecondWriteOffsetWords = kSecondWriteOffsetBytes /
sizeof(uint32_t),
198 kSecondWriteNumWords = kBootDataNumWords - kSecondWriteOffsetWords,
200 RETURN_IF_ERROR(flash_ctrl_info_write(
201 page, offset + kSecondWriteOffsetBytes, kSecondWriteNumWords,
202 (
const char *)
boot_data + kSecondWriteOffsetBytes));
207 flash_ctrl_info_read(page, offset, kBootDataNumWords, &written));
209 return kErrorBootDataWriteCheck;
233 flash_ctrl_info_perms_set(
235 .read = kMultiBitBool4True,
236 .write = kMultiBitBool4True,
238 : kMultiBitBool4False,
240 rom_error_t error = boot_data_entry_write_impl(page, index,
boot_data, erase);
242 .read = kMultiBitBool4False,
243 .write = kMultiBitBool4False,
244 .erase = kMultiBitBool4False,
265 static rom_error_t boot_data_entry_invalidate(
269 static_assert(kBootDataInvalidEntry == 0,
270 "Unexpected kBootDataInvalidEntry value.");
272 const uint32_t offset =
274 const uint32_t val[2] = {0, 0};
276 .read = kMultiBitBool4False,
277 .write = kMultiBitBool4True,
278 .erase = kMultiBitBool4False,
280 rom_error_t error = flash_ctrl_info_write(page, offset, 2, val);
282 .read = kMultiBitBool4False,
283 .write = kMultiBitBool4False,
284 .erase = kMultiBitBool4False,
335 static rom_error_t boot_data_page_info_update_impl(
338 uint32_t sniff_results[kBootDataEntriesPerPage];
344 size_t i = 0, r = kBootDataEntriesPerPage - 1;
345 for (; launder32(i) < kBootDataEntriesPerPage &&
346 launder32(r) < kBootDataEntriesPerPage;
350 HARDENED_RETURN_IF_ERROR(boot_data_sniff(page, i, &sniff_results[i]));
352 if (sniff_results[i] == kFlashCtrlErasedWord) {
353 HARDENED_RETURN_IF_ERROR(boot_data_entry_read(page, i, &buf));
354 has_empty_entry = boot_data_is_empty(&buf);
364 HARDENED_CHECK_LE(i, kBootDataEntriesPerPage);
365 size_t first_empty_index = i;
370 for (--i, ++r; launder32(i) < kBootDataEntriesPerPage &&
371 launder32(r) < kBootDataEntriesPerPage;
374 if (sniff_results[i] == kBootDataIdentifier) {
375 HARDENED_RETURN_IF_ERROR(boot_data_entry_read(page, i, &buf));
376 rom_error_t is_valid = boot_data_check(&buf);
377 if (launder32(is_valid) == kErrorOk) {
380 "kErrorOk must be equal to kHardenedBoolTrue");
399 .has_empty_entry = has_empty_entry,
400 .first_empty_index = first_empty_index,
401 .has_valid_entry = has_valid_entry,
402 .last_valid_index = i,
412 .has_empty_entry = has_empty_entry,
413 .first_empty_index = first_empty_index,
414 .has_valid_entry = has_valid_entry,
415 .last_valid_index = i,
444 static rom_error_t boot_data_page_info_update(
448 .read = kMultiBitBool4True,
449 .write = kMultiBitBool4False,
450 .erase = kMultiBitBool4False,
453 boot_data_page_info_update_impl(page, page_info,
boot_data);
455 .read = kMultiBitBool4False,
456 .write = kMultiBitBool4False,
457 .erase = kMultiBitBool4False,
480 .first_empty_index = kBootDataEntriesPerPage,
482 .last_valid_index = kBootDataEntriesPerPage,
485 static_assert(kPageCount == 2,
486 "Number of pages changed, unrolled loop must be updated");
487 HARDENED_RETURN_IF_ERROR(
488 boot_data_page_info_update(kPages[0], page_info,
boot_data));
489 HARDENED_RETURN_IF_ERROR(
490 boot_data_page_info_update(kPages[1], page_info,
boot_data));
508 static rom_error_t boot_data_default_get(lifecycle_state_t lc_state,
510 uint32_t allowed_in_prod = otp_read32(
511 OTP_CTRL_PARAM_CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN_OFFSET);
512 rom_error_t res = lc_state ^ launder32(kErrorBootDataNotFound);
514 switch (launder32(lc_state)) {
517 res ^= kLcStateTest ^ kErrorBootDataNotFound ^ kErrorOk;
521 res ^= kLcStateDev ^ kErrorBootDataNotFound ^ kErrorOk;
528 res ^= kErrorBootDataNotFound ^ kErrorOk;
531 case kLcStateProdEnd:
533 res ^= kLcStateProdEnd;
536 res ^= kErrorBootDataNotFound ^ kErrorOk;
541 res ^= kLcStateRma ^ kErrorBootDataNotFound ^ kErrorOk;
547 HARDENED_RETURN_IF_ERROR(res);
555 otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT_OFFSET);
557 otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_MIN_SEC_VER_BL0_OFFSET);
580 case kBootDataVersion1:
586 case kBootDataVersion2:
597 HARDENED_RETURN_IF_ERROR(boot_data_active_page_find(&active_page,
boot_data));
604 return boot_data_default_get(lc_state,
boot_data);
613 new_entry.
is_valid = kBootDataValidEntry;
617 RETURN_IF_ERROR(boot_data_active_page_find(&active_page, &last_entry));
623 boot_data_digest_compute(&new_entry, &new_entry.
digest);
625 RETURN_IF_ERROR(boot_data_entry_write(active_page.
page,
632 active_page.
page == kPages[0] ? kPages[1] : kPages[0];
638 RETURN_IF_ERROR(boot_data_entry_invalidate(active_page.
page,
643 new_entry.
counter = kBootDataDefaultCounterVal + 1;
644 boot_data_digest_compute(&new_entry, &new_entry.
digest);
669 static const uint32_t kCheckShares[kHmacDigestNumWords + 1] = {
670 0xe021e1a9, 0xf81e8365, 0xbf8322db, 0xc7a37080, 0x271a933f,
671 0xdd8ce33f, 0x7585d574, 0x951777af, 0x381dee3a,
682 "`digest` must be the first field of `boot_data_t`.");
684 rom_error_t error = kErrorBootDataInvalid;
686 boot_data_digest_compute(
boot_data, &act_digest);
689 for (; launder32(i) < kHmacDigestNumWords; ++i) {
695 if (launder32(error) == kErrorOk) {
700 return kErrorBootDataInvalid;