1 /*
2 * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "config_tfm.h"
9 #include "tfm_plat_otp.h"
10
11 #include "cmsis_compiler.h"
12 #include "dx_reg_base_host.h"
13 #include "tfm_attest_hal.h"
14 #include "uart_stdout.h"
15 #include "region_defs.h"
16 #include "tfm_hal_device_header.h"
17 #include <string.h>
18
19 /* Define some offsets from the CC312 base address, to access particular
20 * registers and memory regions
21 */
22 #define CC312_OTP_BASE_OFFSET 0x2000
23 #define AIB_FUSE_PROG_COMPLETED_REG_OFFSET 0x1F04
24 #define NVM_IS_IDLE_REG_OFFSET 0x1F10
25 #define LCS_IS_VALID_REG_OFFSET 0x1F0C
26 #define OTP_ADDR_WIDTH_DEF_REG_OFFSET 0x1F2C
27 #define LCS_REG_REG_OFFSET 0x1F14
28
cc_read_reg(uint32_t offset)29 static inline uint32_t cc_read_reg(uint32_t offset) {
30 return *((volatile uint32_t*)(DX_BASE_CC + offset));
31 }
32
33
34 /** @struct plat_otp_layout_t
35 * @brief This struct documents the layout of the CC312 OTP. It documents both
36 * the builtin regions, and regions that are added to contain TF-M
37 * data. These added regions are in the "user" area, which is after the
38 * dcu lock mask.
39 *
40 * @var plat_otp_layout_t::huk
41 * The huk field contains the device hardware unique key. Writing to this field
42 * causes the CC312 to transition from CM to DM LCS. This field is used to
43 * store the TF-M HUK.
44 *
45 * @var plat_otp_layout_t::icv_provisioning_key
46 * The icv_provisioning_key field stores the chip manufacturer provisioning
47 * key. This field is unused in TF-M.
48 *
49 * @var plat_otp_layout_t::icv_code_encryption_key
50 * The icv_code_encryption_key field stores the chip manufacturer code
51 * encryption key. This field is unused in TF-M.
52 *
53 * @var plat_otp_layout_t::icv_programmed_flags
54 * The icv_programmed_flags field stores flags related to 4 crypto keys in its
55 * 4 bytes. The fields are encoded such that the lowest 7 bits count the
56 * number of zeroes that appear in the key, and the upper 1 bit, if set,
57 * signals that the key is not used. The HUK field is the exception to this as
58 * it does not have a "not used" bit, and uses all 8 for the zero-count. These
59 * must be set after the HUK has been written, but before the reboot to enable
60 * DM LCS.
61 *
62 * @var plat_otp_layout_t::rot_public_key
63 * This field encodes a public ROT key, and can optionally be split into
64 * separate icv_rot_public_key and oem_rot_public_key fields, each of 128 bits.
65 * Writing to this field causes the CC312 to transition from DM to SE LCS.
66 * This field is used to store the TF-M IAK, utilising both slots for a 256-bit
67 * key.
68 *
69 * @var plat_otp_layout_t::oem_provisioning_secret
70 * The oem_code_encryption_key field stores the device provisioning secret.
71 * This field is unused in TF-M.
72 *
73 * @var plat_otp_layout_t::oem_code_encryption_key
74 * The oem_code_encryption_key field stores the device manufacturer code
75 * encryption key. This field is unused in TF-M.
76 *
77 * @var plat_otp_layout_t::oem_programmed_flags
78 * The icv_programmed_flags field stores flags related to 3 crypto keys in its
79 * first 3 bytes. The fields are encoded such that the lowest 7 bits count the
80 * number of zeroes that appear in the key, and the upper 1 bit, if set,
81 * signals that the key is not used. The rot_public_key field is the exception
82 * to this as it does not have a "not used" bit, and uses all 8 for the
83 * zero-count. These must be set after the rot public key has been written, but
84 * before the reboot to enable SE LCS.
85 *
86 * @var plat_otp_layout_t::nv_counter
87 * The nv_counter field stores either 1 or 2 anti-rollback counters. This field
88 * is unused in TF-M, as it is very small and can not encode enough counter
89 * values to be used for our BL2 images.
90 *
91 * @var plat_otp_layout_t::general_purpose_configuration_flags
92 * The general-purpose configuration flags are used to indicate
93 * implemention-defined configuration, and set in CM LCS. This field is unused
94 * in TF-M.
95 *
96 * @var plat_otp_layout_t::dcu_debug_lock_mask
97 * This field is used to control access to secure debug. It is currently unused
98 * in TF-M.
99 *
100 *
101 * @var plat_otp_layout_t::*_zero_bits
102 * These fields are implemented in the CC312 user-area. They are used in TF-M
103 * to store the number of zero-bits set in other immutable assets stored in
104 * user-area fields. Because the user-area is writable in SE LCS, in order to
105 * make assets immutable the number of zeroes is stored. At boot, the stored
106 * number of zeroes is compared with the actual number in the asset. Due to OTP
107 * semantics, it is only possible to convert 0 bits to 1 bits, so the number of
108 * zeroes in the key can only ever decrease. As the *_zero_bits is encoded as
109 * an unsigned integer, it's not possible to decrease the number saved in the
110 * _zero_bits field, and thus any tampering can be spotted by the comparison.
111 *
112 * @var plat_otp_layout_t::iak_len
113 * This field is implemented in the CC312 user-area. It is used in TF-M to
114 * store the length of the initial attestation key encoded as a uint32_t
115 *
116 * @var plat_otp_layout_t::iak_type
117 * This field is implemented in the CC312 user-area. It is used in TF-M to
118 * store the type of the initial attestation key encoded as a uint32_t
119 *
120 * @var plat_otp_layout_t::iak_id
121 * This field is implemented in the CC312 user-area. It is used in TF-M to
122 * store the id of the initial attestation key encoded as a string
123 *
124 * @var plat_otp_layout_t::boot_seed
125 * This field is implemented in the CC312 user-area. It is used in TF-M to
126 * store the boot seed
127 *
128 * @var plat_otp_layout_t::implementation_id
129 * This field is implemented in the CC312 user-area. It is used in TF-M to
130 * store the implementation_id
131 *
132 * @var plat_otp_layout_t::cert_ref
133 * This field is implemented in the CC312 user-area. It is used in TF-M to
134 * store the certification reference.
135 *
136 * @var plat_otp_layout_t::verification_service_url
137 * This field is implemented in the CC312 user-area. It is used in TF-M to
138 * store the verification_service_url
139 *
140 * @var plat_otp_layout_t::profile_definition
141 * This field is implemented in the CC312 user-area. It is used in TF-M to
142 * store the profile_definition
143 *
144 * @var plat_otp_layout_t::bl2_rotpk
145 * This field is implemented in the CC312 user-area. It is used in TF-M to
146 * store rotpks used by BL2, encoded as a set of 32 byte public key hashes.
147 *
148 * @var plat_otp_layout_t::bl2_nv_counter
149 * This field is implemented in the CC312 user-area. It is used in TF-M to
150 * store nv counters used by BL2.
151 *
152 * @var plat_otp_layout_t::bl1_rotpk
153 * This field is implemented in the CC312 user-area. It is used in TF-M to
154 * store rotpks used by BL1, encoded as a set of 32 byte public key hashes.
155 *
156 * @var plat_otp_layout_t::bl1_nv_counter
157 * This field is implemented in the CC312 user-area. It is used in TF-M to
158 * store nv counters used by BL1.
159 */
160
161 __PACKED_STRUCT plat_otp_layout_t {
162 uint8_t huk[32];
163 uint8_t icv_provisioning_key[16];
164 uint8_t icv_code_encryption_key[16];
165 __PACKED_STRUCT {
166 uint8_t huk_zero_bits;
167 uint8_t icv_provisioning_key_zero_bits;
168 uint8_t icv_code_encryption_key_zero_bits;
169 uint8_t icv_rot_public_key_zero_bits;
170 } icv_programmed_flags;
171 __PACKED_UNION {
172 /* rot_public_key is used for the IAK */
173 uint8_t rot_public_key[32];
174 __PACKED_STRUCT {
175 uint8_t icv_rot_public_key[16];
176 uint8_t oem_rot_public_key[16];
177 };
178 };
179 uint8_t oem_provisioning_secret[16];
180 uint8_t oem_code_encryption_key[16];
181 __PACKED_STRUCT {
182 uint8_t oem_rot_public_key_zero_bits;
183 uint8_t oem_provisioning_secret_zero_bits;
184 uint8_t oem_code_encryption_key_zero_bits;
185 uint8_t rma_flags;
186 } oem_programmed_flags;
187 __PACKED_UNION {
188 uint8_t nv_counter[20];
189 __PACKED_STRUCT {
190 uint8_t icv_nv_counter[8];
191 uint8_t oem_nv_counter[12];
192 };
193 };
194 uint8_t general_purpose_configuration_flags[4];
195 uint8_t dcu_debug_lock_mask[16];
196 /* The user area starts here */
197 __PACKED_STRUCT {
198 __PACKED_STRUCT{
199 uint16_t boot_seed_zero_bits;
200 uint16_t implementation_id_zero_bits;
201 uint16_t cert_ref_zero_bits;
202 uint16_t verification_service_url_zero_bits;
203 uint16_t profile_definition_zero_bits;
204 uint16_t iak_len_zero_bits;
205 uint16_t iak_type_zero_bits;
206 uint16_t iak_id_zero_bits;
207 uint16_t bl2_rotpk_zero_bits[4];
208 #ifdef BL1
209 uint16_t bl1_rotpk_0_zero_bits;
210 #ifdef PLATFORM_DEFAULT_BL1
211 uint16_t bl2_encryption_key_zero_bits;
212 uint16_t bl1_2_image_hash_zero_bits;
213 uint16_t bl2_image_hash_zero_bits;
214 #endif /* PLATFORM_DEFAULT_BL1 */
215 #endif /* BL1 */
216 uint16_t secure_debug_pk_zero_bits;
217 };
218
219 uint8_t iak_len[4];
220 uint8_t iak_type[4];
221 uint8_t iak_id[32];
222
223 uint8_t boot_seed[32];
224 uint8_t implementation_id[32];
225 uint8_t cert_ref[32];
226 uint8_t verification_service_url[32];
227 uint8_t profile_definition[32];
228
229 uint8_t bl2_rotpk[4][32];
230 uint8_t bl2_nv_counter[4][64];
231
232 #ifdef BL1
233 #ifdef PLATFORM_DEFAULT_BL1
234 uint8_t bl1_rotpk_0[56];
235 uint8_t bl1_nv_counter[16];
236
237 uint8_t bl2_encryption_key[32];
238 uint8_t bl1_2_image_hash[32];
239 uint8_t bl2_image_hash[32];
240
241 uint8_t bl1_2_image[BL1_2_CODE_SIZE];
242 uint8_t bl1_2_image_len[4];
243 #else /* PLATFORM_DEFAULT_BL1 */
244 uint8_t bl1_rotpk_0[32];
245 uint8_t bl1_nv_counter[16];
246 #endif /* PLATFORM_DEFAULT_BL1 */
247 #endif /* BL1 */
248
249 #if (PLATFORM_NS_NV_COUNTERS > 0)
250 uint8_t ns_nv_counter_0[64];
251 #endif
252 #if (PLATFORM_NS_NV_COUNTERS > 1)
253 uint8_t ns_nv_counter_1[64];
254 #endif
255 #if (PLATFORM_NS_NV_COUNTERS > 2)
256 uint8_t ns_nv_counter_2[64];
257 #endif
258
259 uint8_t secure_debug_pk[32];
260 };
261 };
262
263 enum cc312_lifecycle_t {
264 CC312_LCS_CM = 0x0,
265 CC312_LCS_DM = 0x1,
266 CC312_LCS_SE = 0x5,
267 CC312_LCS_RMA = 0x7,
268 };
269
get_cc312_otp_ptr(void)270 static inline struct plat_otp_layout_t *get_cc312_otp_ptr(void){
271 return (struct plat_otp_layout_t*)(DX_BASE_CC + CC312_OTP_BASE_OFFSET);
272 }
273
274
275
otp_read(const uint8_t * addr,size_t item_size,size_t out_len,uint8_t * out)276 static enum tfm_plat_err_t otp_read(const uint8_t *addr, size_t item_size,
277 size_t out_len, uint8_t *out)
278 {
279 uint32_t* word_ptr;
280 uint32_t word;
281 uint32_t start_offset;
282 size_t out_done;
283 size_t copy_size;
284 size_t total_copy_size = item_size < out_len ? item_size : out_len;
285
286 /* CC312 OTP can only be read / written in 32 bit words. In order to allow
287 * access to unaligned uint8_t pointers (as per the function definition):
288 *
289 * First calculate nearest aligned pointer (by dropping the last two bits of
290 * the OTP address), and the offset between the OTP address and that aligned
291 * pointer. Load the word from the aligned pointer, and copy the part of
292 * that word after the offset into the output pointer using memcpy (since
293 * the output pointer has no alignment requirements).
294 *
295 * After the first word, all alignment issues will have been resolved. The
296 * only other nuance is making sure we copy the right amount of bytes from
297 * the last word. This is checked for all words, in case the first word is
298 * also the last word.
299 */
300 for(out_done = 0; out_done < total_copy_size;) {
301 start_offset = ((uint32_t)addr + out_done) & 0x3;
302 word_ptr = (uint32_t*)(addr + out_done - start_offset);
303
304 word = *word_ptr;
305
306 copy_size = sizeof(word) - start_offset;
307 if (out_done + copy_size > total_copy_size) {
308 copy_size = total_copy_size - out_done;
309 }
310
311
312 memcpy(out + out_done, ((uint8_t*)&word) + start_offset, copy_size);
313 out_done += copy_size;
314 }
315
316 return TFM_PLAT_ERR_SUCCESS;
317 }
318
wait_until_otp_programming_completes(void)319 void wait_until_otp_programming_completes(void) {
320 /* Read the AIB_FUSE_PROG_COMPLETED register until it has bit 1 set */
321 while (! ( cc_read_reg(AIB_FUSE_PROG_COMPLETED_REG_OFFSET) & 1)) {}
322 }
323
count_buffer_zero_bits(const uint8_t * buf,size_t size)324 static uint32_t count_buffer_zero_bits(const uint8_t* buf, size_t size) {
325 size_t byte_index;
326 uint8_t byte;
327 uint32_t one_count = 0;
328
329 for (byte_index = 0; byte_index < size; byte_index++) {
330 byte = buf[byte_index];
331 for (int bit_index = 0; bit_index < 8; bit_index++) {
332 one_count += (byte >> bit_index) & 1;
333 }
334 }
335
336 return (size * 8) - one_count;
337 }
338
count_otp_zero_bits(const uint8_t * addr,size_t size)339 static uint32_t count_otp_zero_bits(const uint8_t* addr, size_t size) {
340 uint8_t buf[size];
341
342 otp_read(addr, size, sizeof(buf), buf);
343 return count_buffer_zero_bits(buf, size);
344 }
345
otp_write(uint8_t * addr,size_t size,size_t in_len,const uint8_t * in,uint8_t * zero_byte_buf)346 static enum tfm_plat_err_t otp_write(uint8_t *addr, size_t size,
347 size_t in_len, const uint8_t *in,
348 uint8_t* zero_byte_buf)
349 {
350 enum tfm_plat_err_t err;
351 uint32_t* word_ptr;
352 uint32_t current_word;
353 uint32_t word;
354 uint32_t start_offset;
355 size_t in_done = 0;
356 size_t copy_size;
357 uint16_t zero_count;
358
359 if (size < in_len) {
360 return TFM_PLAT_ERR_INVALID_INPUT;
361 }
362
363 /* First iterate through and check all values are valid (will not require a
364 * 1 bit to be unset). See docs below on why certain design choices have
365 * been made with regard to alignment.
366 */
367 for(in_done = 0; in_done < in_len;) {
368 start_offset = ((uint32_t)addr + in_done) & 0x3;
369 word_ptr = (uint32_t*)(addr + in_done - start_offset);
370
371 current_word = *word_ptr;
372 word = 0;
373
374 copy_size = sizeof(word) - start_offset;
375 if (in_done + copy_size > in_len) {
376 copy_size = in_len - in_done;
377 }
378
379 memcpy(((uint8_t*)&word) + start_offset, in + in_done, copy_size);
380 word |= current_word;
381
382 if (memcmp(((uint8_t*)&word) + start_offset, in + in_done, copy_size)) {
383 return TFM_PLAT_ERR_INVALID_INPUT;
384 }
385
386 in_done += copy_size;
387 }
388
389 /* If the caller supplied a zero-count buf, set that. Do this before setting
390 * the OTP in case the zero_count buffer write fails.
391 */
392 if (zero_byte_buf != NULL) {
393 zero_count = count_buffer_zero_bits(in, in_len);
394 if (in_len < size) {
395 /* If the buffer is smaller than the OTP item, count the remainder
396 * of the OTP item as well.
397 */
398 zero_count += count_otp_zero_bits(addr + in_len, size - in_len);
399 }
400
401 err = otp_write(zero_byte_buf, 2, sizeof(zero_count), (uint8_t*)&zero_count, NULL);
402 if (err != TFM_PLAT_ERR_SUCCESS) {
403 return err;
404 }
405 }
406
407 /* CC312 OTP can only be read / written in 32 bit words. In order to allow
408 * access to unaligned uint8_t pointers (as per the function definition):
409 *
410 * First calculate nearest aligned pointer (by dropping the last two bits of
411 * the OTP address), and the offset between the OTP address and that aligned
412 * pointer. Load the word from the aligned pointer, copy from the input
413 * pointer into that word at the offset, and then write the updated word
414 * back to OTP.
415 *
416 * After the first word, all alignment issues will have been resolved. The
417 * only other nuance is making sure we copy the right amount of bytes into
418 * the last word. This is checked for all words, in case the first word is
419 * also the last word.
420 */
421 for(in_done = 0; in_done < in_len;) {
422 start_offset = ((uint32_t)addr + in_done) & 0x3;
423 word_ptr = (uint32_t*)(addr + in_done - start_offset);
424
425 word = *word_ptr;
426
427 copy_size = sizeof(word) - start_offset;
428 if (in_done + copy_size > in_len) {
429 copy_size = in_len - in_done;
430 }
431
432 memcpy(((uint8_t*)&word) + start_offset, in + in_done, copy_size);
433
434 *word_ptr = word;
435 wait_until_otp_programming_completes();
436
437 if (*word_ptr != word) {
438 return TFM_PLAT_ERR_SYSTEM_ERR;
439 }
440
441 in_done += copy_size;
442 }
443
444 return TFM_PLAT_ERR_SUCCESS;
445 }
446
verify_zero_bits_count(uint8_t * buf,size_t buf_len,uint8_t * zero_count_buf)447 static enum tfm_plat_err_t verify_zero_bits_count(uint8_t *buf, size_t buf_len,
448 uint8_t* zero_count_buf)
449 {
450 enum tfm_plat_err_t err;
451 uint16_t zero_count;
452
453 if (buf_len > (UINT16_MAX / 8)) {
454 return TFM_PLAT_ERR_INVALID_INPUT;
455 }
456
457 err = otp_read(zero_count_buf, 2, sizeof(zero_count), (uint8_t*)&zero_count);
458 if (err != TFM_PLAT_ERR_SUCCESS) {
459 return err;
460 }
461
462 if (zero_count != count_otp_zero_bits(buf, buf_len)) {
463 return TFM_PLAT_ERR_SYSTEM_ERR;
464 }
465
466 return TFM_PLAT_ERR_SUCCESS;
467 }
468
check_keys_for_tampering(void)469 static enum tfm_plat_err_t check_keys_for_tampering(void)
470 {
471 size_t idx;
472 enum tfm_plat_err_t err;
473 struct plat_otp_layout_t *otp = get_cc312_otp_ptr();
474
475 err = verify_zero_bits_count(otp->boot_seed,
476 sizeof(otp->boot_seed),
477 (uint8_t*)&otp->boot_seed_zero_bits);
478 if (err != TFM_PLAT_ERR_SUCCESS) {
479 return err;
480 }
481
482 err = verify_zero_bits_count(otp->implementation_id,
483 sizeof(otp->implementation_id),
484 (uint8_t*)&otp->implementation_id_zero_bits);
485 if (err != TFM_PLAT_ERR_SUCCESS) {
486 return err;
487 }
488
489 err = verify_zero_bits_count(otp->cert_ref,
490 sizeof(otp->cert_ref),
491 (uint8_t*)&otp->cert_ref_zero_bits);
492 if (err != TFM_PLAT_ERR_SUCCESS) {
493 return err;
494 }
495
496 err = verify_zero_bits_count(otp->verification_service_url,
497 sizeof(otp->verification_service_url),
498 (uint8_t*)&otp->verification_service_url_zero_bits);
499 if (err != TFM_PLAT_ERR_SUCCESS) {
500 return err;
501 }
502
503 err = verify_zero_bits_count(otp->profile_definition,
504 sizeof(otp->profile_definition),
505 (uint8_t*)&otp->profile_definition_zero_bits);
506 if (err != TFM_PLAT_ERR_SUCCESS) {
507 return err;
508 }
509
510 err = verify_zero_bits_count(otp->iak_len,
511 sizeof(otp->iak_len),
512 (uint8_t*)&otp->iak_len_zero_bits);
513 if (err != TFM_PLAT_ERR_SUCCESS) {
514 return err;
515 }
516
517 err = verify_zero_bits_count(otp->iak_type,
518 sizeof(otp->iak_type),
519 (uint8_t*)&otp->iak_type_zero_bits);
520 if (err != TFM_PLAT_ERR_SUCCESS) {
521 return err;
522 }
523
524 #if ATTEST_INCLUDE_COSE_KEY_ID
525 err = verify_zero_bits_count(otp->iak_id,
526 sizeof(otp->iak_id),
527 (uint8_t*)&otp->iak_id_zero_bits);
528 if (err != TFM_PLAT_ERR_SUCCESS) {
529 return err;
530 }
531 #endif /* ATTEST_INCLUDE_COSE_KEY_ID */
532
533 for(idx = 0; idx < MCUBOOT_IMAGE_NUMBER; idx++) {
534 err = verify_zero_bits_count(otp->bl2_rotpk[idx],
535 sizeof(otp->bl2_rotpk[idx]),
536 (uint8_t*)&otp->bl2_rotpk_zero_bits[idx]);
537 if (err != TFM_PLAT_ERR_SUCCESS) {
538 return err;
539 }
540 }
541
542 #ifdef BL1
543 #ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
544 err = verify_zero_bits_count(otp->secure_debug_pk,
545 sizeof(otp->secure_debug_pk),
546 (uint8_t*)&otp->secure_debug_pk_zero_bits);
547 if (err != TFM_PLAT_ERR_SUCCESS) {
548 return err;
549 }
550 #endif
551
552 err = verify_zero_bits_count(otp->bl1_rotpk_0,
553 sizeof(otp->bl1_rotpk_0),
554 (uint8_t*)&otp->bl1_rotpk_0_zero_bits);
555 if (err != TFM_PLAT_ERR_SUCCESS) {
556 return err;
557 }
558
559 #ifdef PLATFORM_DEFAULT_BL1
560 err = verify_zero_bits_count(otp->bl2_encryption_key,
561 sizeof(otp->bl2_encryption_key),
562 (uint8_t*)&otp->bl2_encryption_key_zero_bits);
563 if (err != TFM_PLAT_ERR_SUCCESS) {
564 return err;
565 }
566
567 err = verify_zero_bits_count(otp->bl1_2_image_hash,
568 sizeof(otp->bl1_2_image_hash),
569 (uint8_t*)&otp->bl1_2_image_hash_zero_bits);
570 if (err != TFM_PLAT_ERR_SUCCESS) {
571 return err;
572 }
573
574 err = verify_zero_bits_count(otp->bl2_image_hash,
575 sizeof(otp->bl2_image_hash),
576 (uint8_t*)&otp->bl2_image_hash_zero_bits);
577 if (err != TFM_PLAT_ERR_SUCCESS) {
578 return err;
579 }
580
581 #endif /* PLATFORM_DEFAULT_BL1 */
582 #endif /* BL1 */
583
584 return TFM_PLAT_ERR_SUCCESS;
585 }
586
map_cc312_lcs_to_otp_lcs(enum cc312_lifecycle_t lcs)587 static enum plat_otp_lcs_t map_cc312_lcs_to_otp_lcs(enum cc312_lifecycle_t lcs) {
588 switch (lcs) {
589 case CC312_LCS_CM:
590 return PLAT_OTP_LCS_ASSEMBLY_AND_TEST;
591 case CC312_LCS_DM:
592 return PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
593 case CC312_LCS_SE:
594 return PLAT_OTP_LCS_SECURED;
595 case CC312_LCS_RMA:
596 return PLAT_OTP_LCS_DECOMMISSIONED;
597 default:
598 return PLAT_OTP_LCS_UNKNOWN;
599 }
600 }
601
otp_read_lcs(size_t out_len,uint8_t * out)602 static enum tfm_plat_err_t otp_read_lcs(size_t out_len, uint8_t *out) {
603 enum cc312_lifecycle_t cc_lcs;
604 enum plat_otp_lcs_t *lcs = (enum plat_otp_lcs_t*) out;
605
606 cc_lcs = cc_read_reg(LCS_REG_REG_OFFSET) & 0x7;
607
608 if (out_len != sizeof(uint32_t)) {
609 return TFM_PLAT_ERR_INVALID_INPUT;
610 }
611
612 *lcs = map_cc312_lcs_to_otp_lcs(cc_lcs);
613
614 return TFM_PLAT_ERR_SUCCESS;
615 }
616
tfm_plat_otp_init(void)617 enum tfm_plat_err_t tfm_plat_otp_init(void)
618 {
619 uint32_t otp_size;
620 uint32_t lcs;
621 enum tfm_plat_err_t err;
622
623
624 /* Wait for the NVM system to become idle */
625 while (! (cc_read_reg(NVM_IS_IDLE_REG_OFFSET) & 1)) {}
626
627 /* Check that the lifecycle state is valid */
628 if (! (cc_read_reg(LCS_IS_VALID_REG_OFFSET) & 1)) {
629 return TFM_PLAT_ERR_SYSTEM_ERR;
630 }
631
632 /* Read the OTP_ADDR_WIDTH_DEF register, and use it to calculate how much
633 * OTP is present. ADDR_WIDTH measures the amount of bits that are used to
634 * index memory, where each bit indexes a memory word. Because binary
635 * indexing is used, the amount of memory words available can be found by
636 * doing 2 to the power of the address width.
637 *
638 * To convert from word to byte addressing (and hence calculate the amount
639 * of bytes available, the amount of words is then multiplied by the size of
640 * a word in bytes.
641 */
642 otp_size = (1 << (cc_read_reg(OTP_ADDR_WIDTH_DEF_REG_OFFSET)))
643 * sizeof(uint32_t);
644 if(sizeof(struct plat_otp_layout_t) > otp_size) {
645 return TFM_PLAT_ERR_SYSTEM_ERR;
646 }
647
648 /* If we are in SE LCS, check keys for tampering. Only applies to keys in
649 * the user storage area, since the others are checked for tampering by HW
650 */
651 otp_read_lcs(sizeof(lcs), (uint8_t*)&lcs);
652 if (lcs == PLAT_OTP_LCS_SECURED) {
653 err = check_keys_for_tampering();
654 if (err != TFM_PLAT_ERR_SUCCESS) {
655 return err;
656 }
657 }
658
659 return TFM_PLAT_ERR_SUCCESS;
660 }
661
tfm_plat_otp_read(enum tfm_otp_element_id_t id,size_t out_len,uint8_t * out)662 enum tfm_plat_err_t tfm_plat_otp_read(enum tfm_otp_element_id_t id,
663 size_t out_len, uint8_t *out)
664 {
665 struct plat_otp_layout_t *otp = get_cc312_otp_ptr();
666
667 switch (id) {
668 case PLAT_OTP_ID_HUK:
669 return otp_read(otp->huk, sizeof(otp->huk), out_len, out);
670 case PLAT_OTP_ID_IAK:
671 /* The IAK is stored in the rot_public_key slot */
672 return otp_read(otp->rot_public_key,
673 sizeof(otp->rot_public_key), out_len, out);
674
675 case PLAT_OTP_ID_BOOT_SEED:
676 return otp_read(otp->boot_seed, sizeof(otp->boot_seed), out_len,
677 out);
678 case PLAT_OTP_ID_LCS:
679 return otp_read_lcs(out_len, out);
680 case PLAT_OTP_ID_IMPLEMENTATION_ID:
681 return otp_read(otp->implementation_id,
682 sizeof(otp->implementation_id), out_len, out);
683 case PLAT_OTP_ID_CERT_REF:
684 return otp_read(otp->cert_ref, sizeof(otp->cert_ref), out_len,
685 out);
686 case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
687 return otp_read(otp->verification_service_url,
688 sizeof(otp->verification_service_url), out_len,
689 out);
690 case PLAT_OTP_ID_PROFILE_DEFINITION:
691 return otp_read(otp->profile_definition,
692 sizeof(otp->profile_definition), out_len, out);
693
694 case PLAT_OTP_ID_IAK_LEN:
695 return otp_read(otp->iak_len,
696 sizeof(otp->iak_len), out_len, out);
697 case PLAT_OTP_ID_IAK_TYPE:
698 return otp_read(otp->iak_type,
699 sizeof(otp->iak_type), out_len, out);
700 case PLAT_OTP_ID_IAK_ID:
701 return otp_read(otp->iak_id,
702 sizeof(otp->iak_id), out_len, out);
703
704 case PLAT_OTP_ID_BL2_ROTPK_0:
705 return otp_read(otp->bl2_rotpk[0], sizeof(otp->bl2_rotpk[0]), out_len,
706 out);
707 case PLAT_OTP_ID_NV_COUNTER_BL2_0:
708 return otp_read(otp->bl2_nv_counter[0],
709 sizeof(otp->bl2_nv_counter[0]), out_len, out);
710
711 case PLAT_OTP_ID_BL2_ROTPK_1:
712 return otp_read(otp->bl2_rotpk[1], sizeof(otp->bl2_rotpk[1]), out_len,
713 out);
714 case PLAT_OTP_ID_NV_COUNTER_BL2_1:
715 return otp_read(otp->bl2_nv_counter[1],
716 sizeof(otp->bl2_nv_counter[1]), out_len, out);
717
718 case PLAT_OTP_ID_BL2_ROTPK_2:
719 return otp_read(otp->bl2_rotpk[2], sizeof(otp->bl2_rotpk[2]), out_len,
720 out);
721 case PLAT_OTP_ID_NV_COUNTER_BL2_2:
722 return otp_read(otp->bl2_nv_counter[2],
723 sizeof(otp->bl2_nv_counter[2]), out_len, out);
724
725 case PLAT_OTP_ID_BL2_ROTPK_3:
726 return otp_read(otp->bl2_rotpk[3], sizeof(otp->bl2_rotpk[3]), out_len,
727 out);
728 case PLAT_OTP_ID_NV_COUNTER_BL2_3:
729 return otp_read(otp->bl2_nv_counter[3],
730 sizeof(otp->bl2_nv_counter[3]), out_len, out);
731
732 #ifdef BL1
733 case PLAT_OTP_ID_BL1_ROTPK_0:
734 return otp_read(otp->bl1_rotpk_0,
735 sizeof(otp->bl1_rotpk_0), out_len, out);
736 case PLAT_OTP_ID_NV_COUNTER_BL1_0:
737 return otp_read(otp->bl1_nv_counter,
738 sizeof(otp->bl1_nv_counter), out_len, out);
739 #ifdef PLATFORM_DEFAULT_BL1
740 case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
741 return otp_read(otp->bl2_encryption_key,
742 sizeof(otp->bl2_encryption_key), out_len, out);
743 case PLAT_OTP_ID_BL1_2_IMAGE_HASH:
744 return otp_read(otp->bl1_2_image_hash,
745 sizeof(otp->bl1_2_image_hash), out_len, out);
746 case PLAT_OTP_ID_BL2_IMAGE_HASH:
747 return otp_read(otp->bl2_image_hash,
748 sizeof(otp->bl2_image_hash), out_len, out);
749 case PLAT_OTP_ID_BL1_2_IMAGE:
750 return otp_read(otp->bl1_2_image,
751 sizeof(otp->bl1_2_image), out_len, out);
752 case PLAT_OTP_ID_BL1_2_IMAGE_LEN:
753 return otp_read(otp->bl1_2_image_len,
754 sizeof(otp->bl1_2_image_len), out_len, out);
755
756 #endif /* PLATFORM_DEFAULT_BL1 */
757 #endif /* BL1 */
758
759 #if (PLATFORM_NS_NV_COUNTERS > 0)
760 case PLAT_OTP_ID_NV_COUNTER_NS_0:
761 return otp_read(otp->ns_nv_counter_0,
762 sizeof(otp->ns_nv_counter_0), out_len, out);
763 #endif
764 #if (PLATFORM_NS_NV_COUNTERS > 1)
765 case PLAT_OTP_ID_NV_COUNTER_NS_1:
766 return otp_read(otp->ns_nv_counter_1,
767 sizeof(otp->ns_nv_counter_1), out_len, out);
768 #endif
769 #if (PLATFORM_NS_NV_COUNTERS > 2)
770 case PLAT_OTP_ID_NV_COUNTER_NS_2:
771 return otp_read(otp->ns_nv_counter_2,
772 sizeof(otp->ns_nv_counter_2), out_len, out);
773 #endif
774
775 case PLAT_OTP_ID_ENTROPY_SEED:
776 return TFM_PLAT_ERR_UNSUPPORTED;
777
778 case PLAT_OTP_ID_SECURE_DEBUG_PK:
779 return otp_read(otp->secure_debug_pk,
780 sizeof(otp->secure_debug_pk), out_len, out);
781
782 default:
783 return TFM_PLAT_ERR_UNSUPPORTED;
784 }
785 }
786
otp_write_lcs(size_t in_len,const uint8_t * in)787 static enum tfm_plat_err_t otp_write_lcs(size_t in_len, const uint8_t *in)
788 {
789 /* Writing the LCS for the CC312 means doing a HW state transition. We need
790 * to reboot to apply this, but first some data about keys we're not using
791 * needs to be written.
792 */
793 uint32_t lcs;
794 enum plat_otp_lcs_t new_lcs = *(uint32_t*)in;
795 enum tfm_plat_err_t err;
796 uint8_t zero_bits;
797 struct plat_otp_layout_t *otp = get_cc312_otp_ptr();
798
799 if (in_len != sizeof(lcs)) {
800 return TFM_PLAT_ERR_INVALID_INPUT;
801 }
802
803 err = otp_read_lcs(sizeof(lcs), (uint8_t*)&lcs);
804 if(err != TFM_PLAT_ERR_SUCCESS) {
805 return err;
806 }
807
808 if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
809 if (new_lcs != PLAT_OTP_LCS_PSA_ROT_PROVISIONING) {
810 return TFM_PLAT_ERR_INVALID_INPUT;
811 }
812
813 /* Test to see if the HUK has been written yet, as this is the trigger
814 * for the LCS transition. Test to see if the zero count has been
815 * written.
816 */
817 err = otp_read(&otp->icv_programmed_flags.huk_zero_bits,
818 sizeof(otp->icv_programmed_flags.huk_zero_bits),
819 sizeof(zero_bits), &zero_bits);
820 if (err != TFM_PLAT_ERR_SUCCESS) {
821 return err;
822 }
823 if (zero_bits == 0) {
824 return TFM_PLAT_ERR_SYSTEM_ERR;
825 }
826
827 /* Set the "not used" bit" for each key */
828 zero_bits = 0x80;
829
830 err = otp_write(&otp->icv_programmed_flags.icv_provisioning_key_zero_bits,
831 sizeof(otp->icv_programmed_flags.icv_provisioning_key_zero_bits),
832 sizeof(zero_bits), &zero_bits, NULL);
833 if (err != TFM_PLAT_ERR_SUCCESS) {
834 return err;
835 }
836
837 err = otp_write(&otp->icv_programmed_flags.icv_code_encryption_key_zero_bits,
838 sizeof(otp->icv_programmed_flags.icv_code_encryption_key_zero_bits),
839 sizeof(zero_bits), &zero_bits, NULL);
840 if (err != TFM_PLAT_ERR_SUCCESS) {
841 return err;
842 }
843
844 err = otp_write(&otp->icv_programmed_flags.icv_rot_public_key_zero_bits,
845 sizeof(otp->icv_programmed_flags.icv_rot_public_key_zero_bits),
846 sizeof(zero_bits), &zero_bits, NULL);
847 if (err != TFM_PLAT_ERR_SUCCESS) {
848 return err;
849 }
850 } else if (lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING) {
851 if (new_lcs != PLAT_OTP_LCS_SECURED) {
852 return TFM_PLAT_ERR_INVALID_INPUT;
853 }
854
855 /* Test to see if the IAK has been written yet, as this is the trigger
856 * for the LCS transition. Test to see if the zero count has been
857 * written.
858 */
859 err = otp_read(&otp->oem_programmed_flags.oem_rot_public_key_zero_bits,
860 sizeof(otp->oem_programmed_flags.oem_rot_public_key_zero_bits),
861 sizeof(zero_bits), &zero_bits);
862 if (err != TFM_PLAT_ERR_SUCCESS) {
863 return err;
864 }
865 if (zero_bits == 0) {
866 return TFM_PLAT_ERR_SYSTEM_ERR;
867 }
868
869 /* Set the "not used" bit" for each key */
870 zero_bits = 0x80;
871
872 err = otp_write(&otp->oem_programmed_flags.oem_provisioning_secret_zero_bits,
873 sizeof(otp->oem_programmed_flags.oem_provisioning_secret_zero_bits),
874 sizeof(zero_bits), &zero_bits, NULL);
875 if (err != TFM_PLAT_ERR_SUCCESS) {
876 return err;
877 }
878
879 err = otp_write(&otp->oem_programmed_flags.oem_code_encryption_key_zero_bits,
880 sizeof(otp->oem_programmed_flags.oem_code_encryption_key_zero_bits),
881 sizeof(zero_bits), &zero_bits, NULL);
882 if (err != TFM_PLAT_ERR_SUCCESS) {
883 return err;
884 }
885 } else {
886 /* TODO transitions for the other LCSes */
887 return TFM_PLAT_ERR_INVALID_INPUT;
888 }
889
890 NVIC_SystemReset();
891 }
892
tfm_plat_otp_write(enum tfm_otp_element_id_t id,size_t in_len,const uint8_t * in)893 enum tfm_plat_err_t tfm_plat_otp_write(enum tfm_otp_element_id_t id,
894 size_t in_len, const uint8_t *in)
895 {
896 struct plat_otp_layout_t *otp = get_cc312_otp_ptr();
897
898 switch (id) {
899 case PLAT_OTP_ID_HUK:
900 return otp_write(otp->huk, sizeof(otp->huk), in_len, in,
901 (uint8_t*)&otp->icv_programmed_flags.huk_zero_bits);
902 case PLAT_OTP_ID_IAK:
903 /* The IAK is stored in the rot_public_key slot */
904 return otp_write(otp->rot_public_key, sizeof(otp->rot_public_key),
905 in_len, in,
906 (uint8_t*)&otp->oem_programmed_flags.oem_rot_public_key_zero_bits);
907
908 case PLAT_OTP_ID_BOOT_SEED:
909 return otp_write(otp->boot_seed, sizeof(otp->boot_seed),
910 in_len, in, (uint8_t*)&otp->boot_seed_zero_bits);
911 case PLAT_OTP_ID_LCS:
912 return otp_write_lcs(in_len, in);
913 case PLAT_OTP_ID_IMPLEMENTATION_ID:
914 return otp_write(otp->implementation_id,
915 sizeof(otp->implementation_id), in_len, in,
916 (uint8_t*)&otp->implementation_id_zero_bits);
917 case PLAT_OTP_ID_CERT_REF:
918 return otp_write(otp->cert_ref, sizeof(otp->cert_ref), in_len,
919 in, (uint8_t*)&otp->cert_ref_zero_bits);
920 case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
921 return otp_write(otp->verification_service_url,
922 sizeof(otp->verification_service_url), in_len, in,
923 (uint8_t*)&otp->verification_service_url_zero_bits);
924 case PLAT_OTP_ID_PROFILE_DEFINITION:
925 return otp_write(otp->profile_definition,
926 sizeof(otp->profile_definition), in_len,
927 in, (uint8_t*)&otp->profile_definition_zero_bits);
928
929 case PLAT_OTP_ID_IAK_LEN:
930 return otp_write(otp->iak_len,
931 sizeof(otp->iak_len), in_len,
932 in, (uint8_t*)&otp->iak_len_zero_bits);
933 case PLAT_OTP_ID_IAK_TYPE:
934 return otp_write(otp->iak_type,
935 sizeof(otp->iak_type), in_len,
936 in, (uint8_t*)&otp->iak_type_zero_bits);
937 case PLAT_OTP_ID_IAK_ID:
938 return otp_write(otp->iak_id,
939 sizeof(otp->iak_id), in_len,
940 in, (uint8_t*)&otp->iak_id_zero_bits);
941
942 case PLAT_OTP_ID_BL2_ROTPK_0:
943 return otp_write(otp->bl2_rotpk[0], sizeof(otp->bl2_rotpk[0]), in_len,
944 in, (uint8_t*)&otp->bl2_rotpk_zero_bits[0]);
945 case PLAT_OTP_ID_NV_COUNTER_BL2_0:
946 return otp_write(otp->bl2_nv_counter[0],
947 sizeof(otp->bl2_nv_counter[0]), in_len, in, NULL);
948
949 case PLAT_OTP_ID_BL2_ROTPK_1:
950 return otp_write(otp->bl2_rotpk[1], sizeof(otp->bl2_rotpk[1]), in_len,
951 in, (uint8_t*)&otp->bl2_rotpk_zero_bits[1]);
952 case PLAT_OTP_ID_NV_COUNTER_BL2_1:
953 return otp_write(otp->bl2_nv_counter[1],
954 sizeof(otp->bl2_nv_counter[1]), in_len, in, NULL);
955
956 case PLAT_OTP_ID_BL2_ROTPK_2:
957 return otp_write(otp->bl2_rotpk[2], sizeof(otp->bl2_rotpk[2]), in_len,
958 in, (uint8_t*)&otp->bl2_rotpk_zero_bits[2]);
959 case PLAT_OTP_ID_NV_COUNTER_BL2_2:
960 return otp_write(otp->bl2_nv_counter[2],
961 sizeof(otp->bl2_nv_counter[2]), in_len, in, NULL);
962
963 case PLAT_OTP_ID_BL2_ROTPK_3:
964 return otp_write(otp->bl2_rotpk[3], sizeof(otp->bl2_rotpk[3]), in_len,
965 in, (uint8_t*)&otp->bl2_rotpk_zero_bits[3]);
966 case PLAT_OTP_ID_NV_COUNTER_BL2_3:
967 return otp_write(otp->bl2_nv_counter[3],
968 sizeof(otp->bl2_nv_counter[3]), in_len, in, NULL);
969
970 #ifdef BL1
971 case PLAT_OTP_ID_BL1_ROTPK_0:
972 return otp_write(otp->bl1_rotpk_0, sizeof(otp->bl1_rotpk_0), in_len, in,
973 (uint8_t*)&otp->bl1_rotpk_0_zero_bits);
974 case PLAT_OTP_ID_NV_COUNTER_BL1_0:
975 return otp_write(otp->bl1_nv_counter,
976 sizeof(otp->bl1_nv_counter), in_len, in, NULL);
977 #ifdef PLATFORM_DEFAULT_BL1
978 case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
979 return otp_write(otp->bl2_encryption_key,
980 sizeof(otp->bl2_encryption_key), in_len, in,
981 (uint8_t*)&otp->bl2_encryption_key_zero_bits);
982 case PLAT_OTP_ID_BL1_2_IMAGE_HASH:
983 return otp_write(otp->bl1_2_image_hash,
984 sizeof(otp->bl1_2_image_hash), in_len, in,
985 (uint8_t*)&otp->bl1_2_image_hash_zero_bits);
986 case PLAT_OTP_ID_BL2_IMAGE_HASH:
987 return otp_write(otp->bl2_image_hash,
988 sizeof(otp->bl2_image_hash), in_len, in,
989 (uint8_t*)&otp->bl2_image_hash_zero_bits);
990 case PLAT_OTP_ID_BL1_2_IMAGE:
991 return otp_write(otp->bl1_2_image,
992 sizeof(otp->bl1_2_image), in_len, in, NULL);
993 case PLAT_OTP_ID_BL1_2_IMAGE_LEN:
994 return otp_write(otp->bl1_2_image_len,
995 sizeof(otp->bl1_2_image_len), in_len, in, NULL);
996
997 #endif /* PLATFORM_DEFAULT_BL1 */
998 #endif /* BL1 */
999
1000 #if (PLATFORM_NS_NV_COUNTERS > 0)
1001 case PLAT_OTP_ID_NV_COUNTER_NS_0:
1002 return otp_write(otp->ns_nv_counter_0,
1003 sizeof(otp->ns_nv_counter_0), in_len, in, NULL);
1004 #endif
1005 #if (PLATFORM_NS_NV_COUNTERS > 1)
1006 case PLAT_OTP_ID_NV_COUNTER_NS_1:
1007 return otp_write(otp->ns_nv_counter_1,
1008 sizeof(otp->ns_nv_counter_1), in_len, in, NULL);
1009 #endif
1010 #if (PLATFORM_NS_NV_COUNTERS > 2)
1011 case PLAT_OTP_ID_NV_COUNTER_NS_2:
1012 return otp_write(otp->ns_nv_counter_2,
1013 sizeof(otp->ns_nv_counter_2), in_len, in, NULL);
1014 #endif
1015
1016 case PLAT_OTP_ID_ENTROPY_SEED:
1017 return TFM_PLAT_ERR_UNSUPPORTED;
1018
1019 case PLAT_OTP_ID_SECURE_DEBUG_PK:
1020 return otp_write(otp->secure_debug_pk,
1021 sizeof(otp->secure_debug_pk), in_len, in,
1022 (uint8_t*)&otp->secure_debug_pk_zero_bits);
1023
1024 default:
1025 return TFM_PLAT_ERR_UNSUPPORTED;
1026 }
1027 }
1028
1029
tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,size_t * size)1030 enum tfm_plat_err_t tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,
1031 size_t *size)
1032 {
1033 struct plat_otp_layout_t *otp = get_cc312_otp_ptr();
1034
1035 switch (id) {
1036 case PLAT_OTP_ID_HUK:
1037 *size = sizeof(otp->huk);
1038 break;
1039 case PLAT_OTP_ID_IAK:
1040 /* The IAK is stored in the rot_public_key slot */
1041 *size = sizeof(otp->rot_public_key);
1042 break;
1043
1044 case PLAT_OTP_ID_BOOT_SEED:
1045 *size = sizeof(otp->boot_seed);
1046 break;
1047 case PLAT_OTP_ID_LCS:
1048 *size = sizeof(uint32_t);
1049 break;
1050 case PLAT_OTP_ID_IMPLEMENTATION_ID:
1051 *size = sizeof(otp->implementation_id);
1052 break;
1053 case PLAT_OTP_ID_CERT_REF:
1054 *size = sizeof(otp->cert_ref);
1055 break;
1056 case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
1057 *size = sizeof(otp->verification_service_url);
1058 break;
1059 case PLAT_OTP_ID_PROFILE_DEFINITION:
1060 *size = sizeof(otp->profile_definition);
1061 break;
1062
1063 case PLAT_OTP_ID_IAK_LEN:
1064 *size = sizeof(otp->iak_len);
1065 break;
1066 case PLAT_OTP_ID_IAK_TYPE:
1067 *size = sizeof(otp->iak_type);
1068 break;
1069 case PLAT_OTP_ID_IAK_ID:
1070 *size = sizeof(otp->iak_id);
1071 break;
1072
1073 case PLAT_OTP_ID_BL2_ROTPK_0:
1074 *size = sizeof(otp->bl2_rotpk[0]);
1075 break;
1076 case PLAT_OTP_ID_NV_COUNTER_BL2_0:
1077 *size = sizeof(otp->bl2_nv_counter[0]);
1078 break;
1079
1080 case PLAT_OTP_ID_BL2_ROTPK_1:
1081 *size = sizeof(otp->bl2_rotpk[1]);
1082 break;
1083 case PLAT_OTP_ID_NV_COUNTER_BL2_1:
1084 *size = sizeof(otp->bl2_nv_counter[1]);
1085 break;
1086
1087 case PLAT_OTP_ID_BL2_ROTPK_2:
1088 *size = sizeof(otp->bl2_rotpk[2]);
1089 break;
1090 case PLAT_OTP_ID_NV_COUNTER_BL2_2:
1091 *size = sizeof(otp->bl2_nv_counter[2]);
1092 break;
1093
1094 case PLAT_OTP_ID_BL2_ROTPK_3:
1095 *size = sizeof(otp->bl2_rotpk[3]);
1096 break;
1097 case PLAT_OTP_ID_NV_COUNTER_BL2_3:
1098 *size = sizeof(otp->bl2_nv_counter[3]);
1099 break;
1100
1101 #ifdef BL1
1102 case PLAT_OTP_ID_BL1_ROTPK_0:
1103 *size = sizeof(otp->bl1_rotpk_0);
1104 break;
1105 case PLAT_OTP_ID_NV_COUNTER_BL1_0:
1106 *size = sizeof(otp->bl1_nv_counter);
1107 break;
1108 #ifdef PLATFORM_DEFAULT_BL1
1109 case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
1110 *size = sizeof(otp->bl2_encryption_key);
1111 break;
1112 case PLAT_OTP_ID_BL1_2_IMAGE_HASH:
1113 *size = sizeof(otp->bl1_2_image_hash);
1114 break;
1115 case PLAT_OTP_ID_BL2_IMAGE_HASH:
1116 *size = sizeof(otp->bl2_image_hash);
1117 break;
1118 case PLAT_OTP_ID_BL1_2_IMAGE:
1119 *size = sizeof(otp->bl1_2_image);
1120 break;
1121 #endif /* PLATFORM_DEFAULT_BL1 */
1122 #endif
1123
1124 #if (PLATFORM_NS_NV_COUNTERS > 0)
1125 case PLAT_OTP_ID_NV_COUNTER_NS_0:
1126 *size = sizeof(otp->ns_nv_counter_0);
1127 break;
1128 #endif
1129 #if (PLATFORM_NS_NV_COUNTERS > 1)
1130 case PLAT_OTP_ID_NV_COUNTER_NS_1:
1131 *size = sizeof(otp->ns_nv_counter_1);
1132 break;
1133 #endif
1134 #if (PLATFORM_NS_NV_COUNTERS > 2)
1135 case PLAT_OTP_ID_NV_COUNTER_NS_2:
1136 *size = sizeof(otp->ns_nv_counter_2);
1137 break;
1138 #endif
1139
1140 case PLAT_OTP_ID_ENTROPY_SEED:
1141 return TFM_PLAT_ERR_UNSUPPORTED;
1142
1143 case PLAT_OTP_ID_SECURE_DEBUG_PK:
1144 *size = sizeof(otp->secure_debug_pk);
1145 break;
1146
1147 default:
1148 return TFM_PLAT_ERR_UNSUPPORTED;
1149 }
1150
1151 return TFM_PLAT_ERR_SUCCESS;
1152 }
1153
tfm_plat_otp_secure_provisioning_start(void)1154 enum tfm_plat_err_t tfm_plat_otp_secure_provisioning_start(void)
1155 {
1156 return TFM_PLAT_ERR_SUCCESS;
1157 }
1158
tfm_plat_otp_secure_provisioning_finish(void)1159 enum tfm_plat_err_t tfm_plat_otp_secure_provisioning_finish(void)
1160 {
1161 return TFM_PLAT_ERR_SUCCESS;
1162 }
1163