5 #include "sw/device/silicon_creator/manuf/lib/personalize.h"
7 #include "sw/device/lib/base/multibits.h"
8 #include "sw/device/lib/base/status.h"
9 #include "sw/device/lib/crypto/drivers/entropy.h"
13 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
14 #include "sw/device/lib/testing/json/provisioning_data.h"
15 #include "sw/device/lib/testing/lc_ctrl_testutils.h"
16 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
17 #include "sw/device/lib/testing/test_framework/check.h"
18 #include "sw/device/silicon_creator/lib/attestation.h"
19 #include "sw/device/silicon_creator/manuf/lib/flash_info_fields.h"
20 #include "sw/device/silicon_creator/manuf/lib/otp_fields.h"
21 #include "sw/device/silicon_creator/manuf/lib/util.h"
23 #include "otp_ctrl_regs.h"
25 static_assert(OTP_CTRL_PARAM_CREATOR_ROOT_KEY_SHARE0_SIZE ==
26 OTP_CTRL_PARAM_CREATOR_ROOT_KEY_SHARE1_SIZE,
27 "Detected Root key share size mismatch");
28 static_assert(OTP_CTRL_PARAM_RMA_TOKEN_SIZE == 16,
29 "RMA token is not 128 bits (i.e., one AES block), re-evaluate "
30 "padding / AES mode. Additionally, update ujson struct "
31 "definition for the wrapped RMA unlock token.");
43 static status_t shares_check(uint64_t *share0, uint64_t *share1,
size_t len) {
44 bool found_error =
false;
45 for (
size_t i = 0; i < len; ++i) {
46 found_error |= share0[i] == share1[i];
47 found_error |= share0[i] == UINT64_MAX || share0[i] == 0;
48 found_error |= share1[i] == UINT64_MAX || share1[0] == 0;
50 return found_error ? INTERNAL() : OK_STATUS();
54 status_t manuf_personalize_flash_asymm_key_seed(
59 uint32_t seed[kAttestationSeedWords];
60 TRY(entropy_csrng_generate(NULL, seed, len,
62 TRY(entropy_csrng_uninstantiate());
66 uint32_t byte_address = 0;
67 if (field.byte_offset == 0) {
68 TRY(flash_ctrl_testutils_info_region_scrambled_setup(
69 flash_state, field.page, field.bank, field.partition, &byte_address));
70 TRY(flash_ctrl_testutils_erase_and_write_page(
71 flash_state, byte_address, field.partition, seed,
72 kDifFlashCtrlPartitionTypeInfo, kAttestationSeedWords));
77 TRY(flash_ctrl_testutils_write(flash_state, byte_address, field.partition,
78 seed, kDifFlashCtrlPartitionTypeInfo,
79 kAttestationSeedWords));
82 uint32_t seed_result[kAttestationSeedWords];
83 TRY(flash_ctrl_testutils_read(flash_state, byte_address, field.partition,
84 seed_result, kDifFlashCtrlPartitionTypeInfo,
87 bool found_error =
false;
88 for (
size_t i = 0; i < len; ++i) {
90 seed[i] == 0 || seed[i] == UINT32_MAX || seed[i] != seed_result[i];
92 return found_error ? INTERNAL() : OK_STATUS();
108 static status_t flash_keymgr_secret_seed_write(
113 uint32_t seed[kFlashInfoKeySeedSizeIn32BitWords];
114 TRY(entropy_csrng_generate(NULL, seed, len,
116 TRY(entropy_csrng_uninstantiate());
118 uint32_t address = 0;
119 TRY(flash_ctrl_testutils_info_region_scrambled_setup(
120 flash_state, field.page, field.bank, field.partition, &address));
122 TRY(flash_ctrl_testutils_erase_and_write_page(
123 flash_state, address, field.partition, seed,
124 kDifFlashCtrlPartitionTypeInfo, len));
126 uint32_t seed_result[kFlashInfoKeySeedSizeIn32BitWords];
127 TRY(flash_ctrl_testutils_read(flash_state, address, field.partition,
128 seed_result, kDifFlashCtrlPartitionTypeInfo,
131 bool found_error =
false;
132 for (
size_t i = 0; i < len; ++i) {
134 seed[i] == 0 || seed[i] == UINT32_MAX || seed[i] != seed_result[i];
136 return found_error ? INTERNAL() : OK_STATUS();
153 static status_t otp_partition_secret2_configure(
154 const dif_otp_ctrl_t *otp_ctrl,
155 const lc_token_hash_t *rma_unlock_token_hash) {
160 uint64_t share0[kRootKeyShareSizeIn64BitWords];
161 TRY(entropy_csrng_generate(NULL, (uint32_t *)share0,
162 kRootKeyShareSizeIn32BitWords,
167 uint64_t share1[kRootKeyShareSizeIn64BitWords];
168 TRY(entropy_csrng_generate(NULL, (uint32_t *)share1,
169 kRootKeyShareSizeIn32BitWords,
171 TRY(entropy_csrng_uninstantiate());
173 TRY(shares_check(share0, share1, kRootKeyShareSizeIn64BitWords));
176 TRY(otp_ctrl_testutils_dai_write64(
178 rma_unlock_token_hash->hash, kRmaUnlockTokenSizeIn64BitWords));
180 kRootKeyOffsetShare0, share0,
181 kRootKeyShareSizeIn64BitWords));
183 kRootKeyOffsetShare1, share1,
184 kRootKeyShareSizeIn64BitWords));
192 status_t manuf_personalize_device_secrets(
194 const dif_otp_ctrl_t *otp_ctrl,
195 const lc_token_hash_t *rma_unlock_token_hash) {
197 TRY(lc_ctrl_testutils_operational_state_check(lc_ctrl));
222 TRY(entropy_complex_init());
226 TRY(flash_keymgr_secret_seed_write(flash_state, kFlashInfoFieldCreatorSeed,
227 kFlashInfoKeySeedSizeIn32BitWords));
231 TRY(flash_keymgr_secret_seed_write(flash_state, kFlashInfoFieldOwnerSeed,
232 kFlashInfoKeySeedSizeIn32BitWords));
235 TRY(otp_partition_secret2_configure(otp_ctrl, rma_unlock_token_hash));
241 static status_t otp_secret_write(
const dif_otp_ctrl_t *otp_ctrl,
242 uint32_t offset,
size_t len) {
246 if (len > kBufferSize) {
253 size_t len_in_32bit_words = len * 2;
254 uint64_t data[kBufferSize];
255 TRY(entropy_csrng_generate(NULL, (uint32_t *)data,
259 bool found_error =
false;
260 uint64_t prev_val = 0;
261 for (
size_t i = 0; i < len; ++i) {
262 found_error |= data[i] == 0 || data[i] == UINT64_MAX || data[i] == prev_val;
274 status_t manuf_personalize_device_secrets_check(
275 const dif_otp_ctrl_t *otp_ctrl) {
279 return is_locked ? OK_STATUS() : INTERNAL();
282 status_t manuf_personalize_device_secret1(
const dif_lc_ctrl_t *lc_ctrl,
283 const dif_otp_ctrl_t *otp_ctrl) {
308 uint32_t otp_hw_cfg1_settings;
310 kHwCfgEnSramIfetchOffset,
311 &otp_hw_cfg1_settings));
312 uint32_t csrng_sw_app_read =
314 if (csrng_sw_app_read != kMultiBitBool8True) {
318 uint32_t dis_rv_dm_late_debug =
320 if (dis_rv_dm_late_debug != kMultiBitBool8True) {
324 TRY(entropy_complex_init());
328 TRY(otp_secret_write(otp_ctrl, kSecret1FlashAddrKeySeedOffset,
329 kSecret1FlashAddrKeySeed64BitWords));
330 TRY(otp_secret_write(otp_ctrl, kSecret1FlashDataKeySeedOffset,
331 kSecret1FlashDataKeySeed64BitWords));
332 TRY(otp_secret_write(otp_ctrl, kSecret1SramDataKeySeedOffset,
333 kSecret1SramDataKeySeed64Bitwords));
335 TRY(entropy_csrng_uninstantiate());
342 status_t manuf_personalize_device_secret1_check(
343 const dif_otp_ctrl_t *otp_ctrl) {
347 return is_locked ? OK_STATUS() : INTERNAL();