1 /*
2 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "tfm_plat_otp.h"
9
10 #include "region_defs.h"
11 #include "cmsis_compiler.h"
12 #include "device_definition.h"
13 #include "lcm_drv.h"
14 #include "cmsis.h"
15 #include "uart_stdout.h"
16 #include "tfm_hal_platform.h"
17
18 __PACKED_STRUCT plat_user_area_layout_t {
19 uint32_t boot_seed_zero_bits;
20 uint32_t implementation_id_zero_bits;
21 uint32_t cert_ref_zero_bits;
22 uint32_t verification_service_url_zero_bits;
23 uint32_t profile_definition_zero_bits;
24 uint32_t iak_len_zero_bits;
25 uint32_t iak_type_zero_bits;
26 uint32_t iak_id_zero_bits;
27 uint32_t bl2_rotpk_zero_bits[3];
28 uint32_t bl2_encryption_key_zero_bits;
29 uint32_t bl1_2_image_hash_zero_bits;
30 uint32_t bl2_image_hash_zero_bits;
31 uint32_t bl1_rotpk_0_zero_bits;
32 uint32_t secure_debug_pk_zero_bits;
33 uint32_t host_rotpk_s_zero_bits;
34 uint32_t host_rotpk_ns_zero_bits;
35 uint32_t host_rotpk_cca_zero_bits;
36 uint32_t cca_system_properties_zero_bits;
37
38 uint32_t iak_len;
39 uint32_t iak_type;
40 uint32_t iak_id[8];
41
42 uint32_t boot_seed[8];
43 uint32_t implementation_id[8];
44 uint32_t cert_ref[8];
45 uint32_t verification_service_url[8];
46 uint32_t profile_definition[8];
47
48 uint32_t bl2_rotpk[3][8];
49 uint32_t bl2_nv_counter[4][128];
50
51 uint32_t bl2_encryption_key[8];
52 uint32_t bl1_2_image_hash[8];
53 uint32_t bl2_image_hash[8];
54 uint32_t bl1_nv_counter[128];
55
56 uint32_t secure_debug_pk[8];
57
58 uint32_t host_nv_counter[3][128];
59
60 uint32_t bl1_rotpk_0[14];
61
62 uint32_t host_rotpk_s[24];
63 uint32_t host_rotpk_ns[24];
64 uint32_t host_rotpk_cca[24];
65
66 uint32_t cca_system_properties;
67
68 uint32_t bl1_2_image[BL1_2_CODE_SIZE / sizeof(uint32_t)];
69 };
70
71 #ifdef NDEBUG
72 #define LOG(str)
73 #else
74 #define LOG(str) do { \
75 stdio_output_string((const unsigned char *)str, sizeof(str) - 1); \
76 } while (0);
77 #endif /* NDEBUG */
78
79 #define OTP_OFFSET(x) (offsetof(struct lcm_otp_layout_t, x))
80 #define OTP_SIZE(x) (sizeof(((struct lcm_otp_layout_t *)0)->x))
81 #define USER_AREA_OFFSET(x) (OTP_OFFSET(user_data) + \
82 offsetof(struct plat_user_area_layout_t, x))
83 #define USER_AREA_SIZE(x) (sizeof(((struct plat_user_area_layout_t *)0)->x))
84
count_buffer_zero_bits(const uint8_t * buf,size_t size)85 static uint32_t count_buffer_zero_bits(const uint8_t* buf, size_t size)
86 {
87 size_t byte_index;
88 uint8_t byte;
89 uint32_t one_count = 0;
90
91 for (byte_index = 0; byte_index < size; byte_index++) {
92 byte = buf[byte_index];
93 for (int bit_index = 0; bit_index < 8; bit_index++) {
94 one_count += (byte >> bit_index) & 1;
95 }
96 }
97
98 return (size * 8) - one_count;
99 }
100
otp_read(uint32_t offset,uint32_t len,uint32_t buf_len,uint8_t * buf)101 static enum tfm_plat_err_t otp_read(uint32_t offset, uint32_t len,
102 uint32_t buf_len, uint8_t *buf)
103 {
104 if (buf_len < len) {
105 len = buf_len;
106 }
107
108 if (lcm_otp_read(&LCM_DEV_S, offset, len, buf) != LCM_ERROR_NONE) {
109 return TFM_PLAT_ERR_SYSTEM_ERR;
110 } else {
111 return TFM_PLAT_ERR_SUCCESS;
112 }
113 }
114
otp_write(uint32_t offset,uint32_t len,uint32_t buf_len,const uint8_t * buf,uint32_t zero_count_offset)115 static enum tfm_plat_err_t otp_write(uint32_t offset, uint32_t len,
116 uint32_t buf_len, const uint8_t *buf,
117 uint32_t zero_count_offset)
118 {
119 uint32_t zero_count;
120 enum lcm_error_t err;
121
122 if (buf_len > len) {
123 return TFM_PLAT_ERR_INVALID_INPUT;
124 }
125
126 err = lcm_otp_write(&LCM_DEV_S, offset, buf_len, buf);
127 if (err != LCM_ERROR_NONE) {
128 return TFM_PLAT_ERR_SYSTEM_ERR;
129 }
130
131 if (zero_count_offset != 0) {
132 zero_count = count_buffer_zero_bits(buf, buf_len);
133
134 err = lcm_otp_write(&LCM_DEV_S, zero_count_offset, sizeof(zero_count),
135 (uint8_t *)&zero_count);
136 if (err != LCM_ERROR_NONE) {
137 return TFM_PLAT_ERR_SYSTEM_ERR;
138 }
139 }
140
141 return TFM_PLAT_ERR_SUCCESS;
142 }
143
count_otp_zero_bits(uint32_t offset,uint32_t len)144 static uint32_t count_otp_zero_bits(uint32_t offset, uint32_t len)
145 {
146 uint8_t buf[len];
147
148 otp_read(offset, len, len, buf);
149 return count_buffer_zero_bits(buf, len);
150 }
151
verify_zero_bits_count(uint32_t offset,uint32_t len,uint32_t zero_count_offset)152 static enum tfm_plat_err_t verify_zero_bits_count(uint32_t offset,
153 uint32_t len,
154 uint32_t zero_count_offset)
155 {
156 enum lcm_error_t lcm_err;
157 uint32_t zero_count;
158
159 lcm_err = lcm_otp_read(&LCM_DEV_S, zero_count_offset, sizeof(zero_count),
160 (uint8_t*)&zero_count);
161 if (lcm_err != LCM_ERROR_NONE) {
162 return TFM_PLAT_ERR_SYSTEM_ERR;
163 }
164
165 if (zero_count != count_otp_zero_bits(offset, len)) {
166 return TFM_PLAT_ERR_SYSTEM_ERR;
167 }
168
169 return TFM_PLAT_ERR_SUCCESS;
170 }
171
check_keys_for_tampering(void)172 static enum tfm_plat_err_t check_keys_for_tampering(void)
173 {
174 size_t idx;
175 uint32_t zero_count;
176 enum tfm_plat_err_t err;
177
178 err = verify_zero_bits_count(USER_AREA_OFFSET(boot_seed),
179 USER_AREA_SIZE(boot_seed),
180 USER_AREA_OFFSET(boot_seed_zero_bits));
181 if (err != TFM_PLAT_ERR_SUCCESS) {
182 return err;
183 }
184
185 err = verify_zero_bits_count(USER_AREA_OFFSET(implementation_id),
186 USER_AREA_SIZE(implementation_id),
187 USER_AREA_OFFSET(implementation_id_zero_bits));
188 if (err != TFM_PLAT_ERR_SUCCESS) {
189 return err;
190 }
191
192 err = verify_zero_bits_count(USER_AREA_OFFSET(cert_ref),
193 USER_AREA_SIZE(cert_ref),
194 USER_AREA_OFFSET(cert_ref_zero_bits));
195 if (err != TFM_PLAT_ERR_SUCCESS) {
196 return err;
197 }
198
199 err = verify_zero_bits_count(USER_AREA_OFFSET(verification_service_url),
200 USER_AREA_SIZE(verification_service_url),
201 USER_AREA_OFFSET(verification_service_url_zero_bits));
202 if (err != TFM_PLAT_ERR_SUCCESS) {
203 return err;
204 }
205
206 err = verify_zero_bits_count(USER_AREA_OFFSET(profile_definition),
207 USER_AREA_SIZE(profile_definition),
208 USER_AREA_OFFSET(profile_definition_zero_bits));
209 if (err != TFM_PLAT_ERR_SUCCESS) {
210 return err;
211 }
212
213 /* The rotpk (used as the ROTPK for the RSS rutime) is special as it's zero
214 * count is stored in the cm_config_2 field, but it's not checked so we
215 * still need to do it manually
216 */
217 otp_read(OTP_OFFSET(cm_config_2), OTP_SIZE(cm_config_2), sizeof(zero_count),
218 (uint8_t *)&zero_count);
219
220 zero_count &= 0xff;
221
222 if (zero_count != count_otp_zero_bits(OTP_OFFSET(rotpk), OTP_SIZE(rotpk))) {
223 return TFM_PLAT_ERR_SYSTEM_ERR;
224 }
225
226 /* First bl2 ROTPK is stored in the ROTPK slot, validate the others */
227 for (idx = 0; idx < MCUBOOT_IMAGE_NUMBER - 1; idx++) {
228 err = verify_zero_bits_count(USER_AREA_OFFSET(bl2_rotpk[idx]),
229 USER_AREA_SIZE(bl2_rotpk[idx]),
230 USER_AREA_OFFSET(bl2_rotpk_zero_bits[idx]));
231 if (err != TFM_PLAT_ERR_SUCCESS) {
232 return err;
233 }
234 }
235
236 #ifdef BL1
237 err = verify_zero_bits_count(USER_AREA_OFFSET(bl2_encryption_key),
238 USER_AREA_SIZE(bl2_encryption_key),
239 USER_AREA_OFFSET(bl2_encryption_key_zero_bits));
240 if (err != TFM_PLAT_ERR_SUCCESS) {
241 return err;
242 }
243
244 #ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
245 err = verify_zero_bits_count(USER_AREA_OFFSET(secure_debug_pk),
246 USER_AREA_SIZE(secure_debug_pk),
247 USER_AREA_OFFSET(secure_debug_pk_zero_bits));
248 if (err != TFM_PLAT_ERR_SUCCESS) {
249 return err;
250 }
251 #endif
252
253 err = verify_zero_bits_count(USER_AREA_OFFSET(bl1_2_image_hash),
254 USER_AREA_SIZE(bl1_2_image_hash),
255 USER_AREA_OFFSET(bl1_2_image_hash_zero_bits));
256 if (err != TFM_PLAT_ERR_SUCCESS) {
257 return err;
258 }
259
260 err = verify_zero_bits_count(USER_AREA_OFFSET(bl2_image_hash),
261 USER_AREA_SIZE(bl2_image_hash),
262 USER_AREA_OFFSET(bl2_image_hash_zero_bits));
263 if (err != TFM_PLAT_ERR_SUCCESS) {
264 return err;
265 }
266
267 err = verify_zero_bits_count(USER_AREA_OFFSET(bl1_rotpk_0),
268 USER_AREA_SIZE(bl1_rotpk_0),
269 USER_AREA_OFFSET(bl1_rotpk_0_zero_bits));
270 if (err != TFM_PLAT_ERR_SUCCESS) {
271 return err;
272 }
273 #endif /* BL1 */
274
275 err = verify_zero_bits_count(USER_AREA_OFFSET(host_rotpk_s),
276 USER_AREA_SIZE(host_rotpk_s),
277 USER_AREA_OFFSET(host_rotpk_s_zero_bits));
278 if (err != TFM_PLAT_ERR_SUCCESS) {
279 return err;
280 }
281
282 err = verify_zero_bits_count(USER_AREA_OFFSET(host_rotpk_ns),
283 USER_AREA_SIZE(host_rotpk_ns),
284 USER_AREA_OFFSET(host_rotpk_ns_zero_bits));
285 if (err != TFM_PLAT_ERR_SUCCESS) {
286 return err;
287 }
288
289 err = verify_zero_bits_count(USER_AREA_OFFSET(host_rotpk_cca),
290 USER_AREA_SIZE(host_rotpk_cca),
291 USER_AREA_OFFSET(host_rotpk_cca_zero_bits));
292 if (err != TFM_PLAT_ERR_SUCCESS) {
293 return err;
294 }
295
296 err = verify_zero_bits_count(USER_AREA_OFFSET(cca_system_properties),
297 USER_AREA_SIZE(cca_system_properties),
298 USER_AREA_OFFSET(cca_system_properties_zero_bits));
299 if (err != TFM_PLAT_ERR_SUCCESS) {
300 return err;
301 }
302
303 return TFM_PLAT_ERR_SUCCESS;
304 }
305
map_otp_lcs_to_lcm_lcs(enum plat_otp_lcs_t lcs)306 static enum lcm_lcs_t map_otp_lcs_to_lcm_lcs(enum plat_otp_lcs_t lcs)
307 {
308 switch (lcs) {
309 case PLAT_OTP_LCS_ASSEMBLY_AND_TEST:
310 return LCM_LCS_CM;
311 case PLAT_OTP_LCS_PSA_ROT_PROVISIONING:
312 return LCM_LCS_DM;
313 case PLAT_OTP_LCS_SECURED:
314 return LCM_LCS_SE;
315 case PLAT_OTP_LCS_DECOMMISSIONED:
316 return LCM_LCS_RMA;
317 default:
318 return LCM_LCS_INVALID;
319 }
320 }
321
map_lcm_lcs_to_otp_lcs(enum lcm_lcs_t lcs)322 static enum plat_otp_lcs_t map_lcm_lcs_to_otp_lcs(enum lcm_lcs_t lcs)
323 {
324 switch (lcs) {
325 case LCM_LCS_CM:
326 return PLAT_OTP_LCS_ASSEMBLY_AND_TEST;
327 case LCM_LCS_DM:
328 return PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
329 case LCM_LCS_SE:
330 return PLAT_OTP_LCS_SECURED;
331 case LCM_LCS_RMA:
332 return PLAT_OTP_LCS_DECOMMISSIONED;
333 default:
334 return PLAT_OTP_LCS_UNKNOWN;
335 }
336 }
337
otp_read_lcs(size_t out_len,uint8_t * out)338 static enum tfm_plat_err_t otp_read_lcs(size_t out_len, uint8_t *out)
339 {
340 enum lcm_lcs_t lcm_lcs;
341 enum plat_otp_lcs_t *lcs = (enum plat_otp_lcs_t*) out;
342
343 if (lcm_get_lcs(&LCM_DEV_S, &lcm_lcs)) {
344 return TFM_PLAT_ERR_SYSTEM_ERR;
345 }
346
347 if (out_len != sizeof(uint32_t)) {
348 return TFM_PLAT_ERR_INVALID_INPUT;
349 }
350
351 *lcs = map_lcm_lcs_to_otp_lcs(lcm_lcs);
352
353 return TFM_PLAT_ERR_SUCCESS;
354 }
355
tfm_plat_otp_init(void)356 enum tfm_plat_err_t tfm_plat_otp_init(void)
357 {
358 uint32_t otp_size;
359 enum lcm_error_t err;
360 enum lcm_lcs_t lcs;
361 enum tfm_plat_err_t plat_err;
362 enum lcm_bool_t sp_enabled;
363 enum lcm_tp_mode_t tp_mode;
364
365 err = lcm_get_otp_size(&LCM_DEV_S, &otp_size);
366 if (err != LCM_ERROR_NONE) {
367 return TFM_PLAT_ERR_SYSTEM_ERR;
368 }
369
370 if (otp_size < OTP_OFFSET(user_data) +
371 sizeof(struct plat_user_area_layout_t)) {
372 return TFM_PLAT_ERR_SYSTEM_ERR;
373 }
374
375 err = lcm_get_tp_mode(&LCM_DEV_S, &tp_mode);
376 if (err != LCM_ERROR_NONE) {
377 return TFM_PLAT_ERR_SYSTEM_ERR;
378 }
379 if (tp_mode == LCM_TP_MODE_VIRGIN) {
380 err = lcm_set_tp_mode(&LCM_DEV_S, LCM_TP_MODE_TCI);
381 if (err != LCM_ERROR_NONE) {
382 return TFM_PLAT_ERR_SYSTEM_ERR;
383 }
384 LOG("TP mode set complete, reset now.\r\n");
385 tfm_hal_system_reset();
386 } else if (!(tp_mode == LCM_TP_MODE_TCI || tp_mode == LCM_TP_MODE_PCI)) {
387 return TFM_PLAT_ERR_SYSTEM_ERR;
388 }
389
390 err = lcm_get_lcs(&LCM_DEV_S, &lcs);
391 if (err != LCM_ERROR_NONE) {
392 return TFM_PLAT_ERR_SYSTEM_ERR;
393 }
394 if (lcs == LCM_LCS_CM || lcs == LCM_LCS_DM) {
395 err = lcm_get_sp_enabled(&LCM_DEV_S, &sp_enabled);
396 if (err != LCM_ERROR_NONE) {
397 return TFM_PLAT_ERR_SYSTEM_ERR;
398 }
399
400 if (sp_enabled != LCM_TRUE) {
401 LOG("Enabling secure provisioning mode\r\n");
402 lcm_set_sp_enabled(&LCM_DEV_S);
403 }
404 } else if (lcs == LCM_LCS_SE) {
405 /* If we are in SE LCS, check keys for tampering. Only applies to keys
406 * in the user storage area, since the others are checked for tampering
407 * by HW.
408 */
409 plat_err = check_keys_for_tampering();
410 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
411 return plat_err;
412 }
413 }
414
415 return TFM_PLAT_ERR_SUCCESS;
416 }
417
tfm_plat_otp_read(enum tfm_otp_element_id_t id,size_t out_len,uint8_t * out)418 enum tfm_plat_err_t tfm_plat_otp_read(enum tfm_otp_element_id_t id,
419 size_t out_len, uint8_t *out)
420 {
421 switch (id) {
422 case PLAT_OTP_ID_HUK:
423 return otp_read(OTP_OFFSET(huk), OTP_SIZE(huk), out_len, out);
424 case PLAT_OTP_ID_GUK:
425 return otp_read(OTP_OFFSET(guk), OTP_SIZE(guk), out_len, out);
426
427 case PLAT_OTP_ID_BOOT_SEED:
428 return otp_read(USER_AREA_OFFSET(boot_seed), USER_AREA_SIZE(boot_seed),
429 out_len, out);
430 case PLAT_OTP_ID_LCS:
431 return otp_read_lcs(out_len, out);
432 case PLAT_OTP_ID_IMPLEMENTATION_ID:
433 return otp_read(USER_AREA_OFFSET(implementation_id),
434 USER_AREA_SIZE(implementation_id), out_len, out);
435 case PLAT_OTP_ID_CERT_REF:
436 return otp_read(USER_AREA_OFFSET(cert_ref),
437 USER_AREA_SIZE(cert_ref), out_len, out);
438 case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
439 return otp_read(USER_AREA_OFFSET(verification_service_url),
440 USER_AREA_SIZE(verification_service_url), out_len,
441 out);
442 case PLAT_OTP_ID_PROFILE_DEFINITION:
443 return otp_read(USER_AREA_OFFSET(profile_definition),
444 USER_AREA_SIZE(profile_definition), out_len, out);
445
446 case PLAT_OTP_ID_BL2_ROTPK_0:
447 return otp_read(OTP_OFFSET(rotpk), OTP_SIZE(rotpk), out_len, out);
448 case PLAT_OTP_ID_NV_COUNTER_BL2_0:
449 return otp_read(USER_AREA_OFFSET(bl2_nv_counter[0]),
450 USER_AREA_SIZE(bl2_nv_counter[0]), out_len, out);
451
452 case PLAT_OTP_ID_BL2_ROTPK_1:
453 return otp_read(USER_AREA_OFFSET(bl2_rotpk[0]),
454 USER_AREA_SIZE(bl2_rotpk[0]), out_len, out);
455 case PLAT_OTP_ID_NV_COUNTER_BL2_1:
456 return otp_read(USER_AREA_OFFSET(bl2_nv_counter[1]),
457 USER_AREA_SIZE(bl2_nv_counter[1]), out_len, out);
458
459 case PLAT_OTP_ID_BL2_ROTPK_2:
460 return otp_read(USER_AREA_OFFSET(bl2_rotpk[1]),
461 USER_AREA_SIZE(bl2_rotpk[1]), out_len, out);
462 case PLAT_OTP_ID_NV_COUNTER_BL2_2:
463 return otp_read(USER_AREA_OFFSET(bl2_nv_counter[2]),
464 USER_AREA_SIZE(bl2_nv_counter[2]), out_len, out);
465
466 case PLAT_OTP_ID_BL2_ROTPK_3:
467 return otp_read(USER_AREA_OFFSET(bl2_rotpk[2]),
468 USER_AREA_SIZE(bl2_rotpk[2]), out_len, out);
469 case PLAT_OTP_ID_NV_COUNTER_BL2_3:
470 return otp_read(USER_AREA_OFFSET(bl2_nv_counter[3]),
471 USER_AREA_SIZE(bl2_nv_counter[3]), out_len, out);
472
473 case PLAT_OTP_ID_NV_COUNTER_NS_0:
474 return otp_read(USER_AREA_OFFSET(host_nv_counter[0]),
475 USER_AREA_SIZE(host_nv_counter[0]), out_len, out);
476 case PLAT_OTP_ID_NV_COUNTER_NS_1:
477 return otp_read(USER_AREA_OFFSET(host_nv_counter[1]),
478 USER_AREA_SIZE(host_nv_counter[1]), out_len, out);
479 case PLAT_OTP_ID_NV_COUNTER_NS_2:
480 return otp_read(USER_AREA_OFFSET(host_nv_counter[2]),
481 USER_AREA_SIZE(host_nv_counter[2]), out_len, out);
482
483 #ifdef BL1
484 case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
485 return otp_read(USER_AREA_OFFSET(bl2_encryption_key),
486 USER_AREA_SIZE(bl2_encryption_key), out_len, out);
487 case PLAT_OTP_ID_BL1_2_IMAGE_HASH:
488 return otp_read(USER_AREA_OFFSET(bl1_2_image_hash),
489 USER_AREA_SIZE(bl1_2_image_hash), out_len, out);
490 case PLAT_OTP_ID_BL2_IMAGE_HASH:
491 return otp_read(USER_AREA_OFFSET(bl2_image_hash),
492 USER_AREA_SIZE(bl2_image_hash), out_len, out);
493 case PLAT_OTP_ID_NV_COUNTER_BL1_0:
494 return otp_read(USER_AREA_OFFSET(bl1_nv_counter),
495 USER_AREA_SIZE(bl1_nv_counter), out_len, out);
496 case PLAT_OTP_ID_BL1_ROTPK_0:
497 return otp_read(USER_AREA_OFFSET(bl1_rotpk_0),
498 USER_AREA_SIZE(bl1_rotpk_0), out_len, out);
499 case PLAT_OTP_ID_BL1_2_IMAGE:
500 return otp_read(USER_AREA_OFFSET(bl1_2_image),
501 USER_AREA_SIZE(bl1_2_image), out_len, out);
502 #endif /* BL1 */
503
504 case PLAT_OTP_ID_ENTROPY_SEED:
505 return TFM_PLAT_ERR_UNSUPPORTED;
506
507 case PLAT_OTP_ID_SECURE_DEBUG_PK:
508 return otp_read(USER_AREA_OFFSET(secure_debug_pk),
509 USER_AREA_SIZE(secure_debug_pk), out_len, out);
510
511 case PLAT_OTP_ID_HOST_ROTPK_S:
512 return otp_read(USER_AREA_OFFSET(host_rotpk_s),
513 USER_AREA_SIZE(host_rotpk_s), out_len, out);
514 case PLAT_OTP_ID_HOST_ROTPK_NS:
515 return otp_read(USER_AREA_OFFSET(host_rotpk_ns),
516 USER_AREA_SIZE(host_rotpk_ns), out_len, out);
517 case PLAT_OTP_ID_HOST_ROTPK_CCA:
518 return otp_read(USER_AREA_OFFSET(host_rotpk_cca),
519 USER_AREA_SIZE(host_rotpk_cca), out_len, out);
520
521 case PLAT_OTP_ID_CCA_SYSTEM_PROPERTIES:
522 return otp_read(USER_AREA_OFFSET(cca_system_properties),
523 USER_AREA_SIZE(cca_system_properties), out_len, out);
524
525 default:
526 return TFM_PLAT_ERR_UNSUPPORTED;
527 }
528 }
529
otp_write_lcs(size_t in_len,const uint8_t * in)530 static enum tfm_plat_err_t otp_write_lcs(size_t in_len, const uint8_t *in)
531 {
532 uint32_t lcs;
533 enum plat_otp_lcs_t new_lcs = *(uint32_t*)in;
534 enum lcm_error_t lcm_err;
535 uint16_t gppc_val = 0;
536
537 if (in_len != sizeof(lcs)) {
538 return TFM_PLAT_ERR_INVALID_INPUT;
539 }
540
541 lcm_err = lcm_set_lcs(&LCM_DEV_S, map_otp_lcs_to_lcm_lcs(new_lcs), gppc_val);
542 if (lcm_err != LCM_ERROR_NONE) {
543 return TFM_PLAT_ERR_SYSTEM_ERR;
544 }
545
546 LOG("LCS transition complete, resetting now.\r\n");
547
548 tfm_hal_system_reset();
549
550 /* This should never happen */
551 return TFM_PLAT_ERR_SUCCESS;
552 }
553
tfm_plat_otp_write(enum tfm_otp_element_id_t id,size_t in_len,const uint8_t * in)554 enum tfm_plat_err_t tfm_plat_otp_write(enum tfm_otp_element_id_t id,
555 size_t in_len, const uint8_t *in)
556 {
557 switch (id) {
558 case PLAT_OTP_ID_HUK:
559 return otp_write(OTP_OFFSET(huk), OTP_SIZE(huk), in_len, in,
560 0);
561 case PLAT_OTP_ID_GUK:
562 return otp_write(OTP_OFFSET(guk), OTP_SIZE(guk), in_len, in,
563 0);
564
565 case PLAT_OTP_ID_BOOT_SEED:
566 return otp_write(USER_AREA_OFFSET(boot_seed), USER_AREA_SIZE(boot_seed),
567 in_len, in, USER_AREA_OFFSET(boot_seed_zero_bits));
568 case PLAT_OTP_ID_LCS:
569 return otp_write_lcs(in_len, in);
570 case PLAT_OTP_ID_IMPLEMENTATION_ID:
571 return otp_write(USER_AREA_OFFSET(implementation_id),
572 USER_AREA_SIZE(implementation_id), in_len, in,
573 USER_AREA_OFFSET(implementation_id_zero_bits));
574 case PLAT_OTP_ID_CERT_REF:
575 return otp_write(USER_AREA_OFFSET(cert_ref),
576 USER_AREA_SIZE(cert_ref), in_len, in,
577 USER_AREA_OFFSET(cert_ref_zero_bits));
578 case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
579 return otp_write(USER_AREA_OFFSET(verification_service_url),
580 USER_AREA_SIZE(verification_service_url), in_len, in,
581 USER_AREA_OFFSET(verification_service_url_zero_bits));
582 case PLAT_OTP_ID_PROFILE_DEFINITION:
583 return otp_write(USER_AREA_OFFSET(profile_definition),
584 USER_AREA_SIZE(profile_definition), in_len,
585 in, USER_AREA_OFFSET(profile_definition_zero_bits));
586
587 case PLAT_OTP_ID_BL2_ROTPK_0:
588 return otp_write(OTP_OFFSET(rotpk), OTP_SIZE(rotpk), in_len, in, 0);
589 case PLAT_OTP_ID_NV_COUNTER_BL2_0:
590 return otp_write(USER_AREA_OFFSET(bl2_nv_counter[0]),
591 USER_AREA_SIZE(bl2_nv_counter[0]), in_len, in, 0);
592
593 case PLAT_OTP_ID_BL2_ROTPK_1:
594 return otp_write(USER_AREA_OFFSET(bl2_rotpk[0]),
595 USER_AREA_SIZE(bl2_rotpk[0]), in_len, in,
596 USER_AREA_OFFSET(bl2_rotpk_zero_bits[0]));
597 case PLAT_OTP_ID_NV_COUNTER_BL2_1:
598 return otp_write(USER_AREA_OFFSET(bl2_nv_counter[1]),
599 USER_AREA_SIZE(bl2_nv_counter[1]), in_len, in, 0);
600
601 case PLAT_OTP_ID_BL2_ROTPK_2:
602 return otp_write(USER_AREA_OFFSET(bl2_rotpk[1]),
603 USER_AREA_SIZE(bl2_rotpk[1]), in_len, in,
604 USER_AREA_OFFSET(bl2_rotpk_zero_bits[1]));
605 case PLAT_OTP_ID_NV_COUNTER_BL2_2:
606 return otp_write(USER_AREA_OFFSET(bl2_nv_counter[2]),
607 USER_AREA_SIZE(bl2_nv_counter[2]), in_len, in, 0);
608
609 case PLAT_OTP_ID_BL2_ROTPK_3:
610 return otp_write(USER_AREA_OFFSET(bl2_rotpk[2]),
611 USER_AREA_SIZE(bl2_rotpk[2]), in_len, in,
612 USER_AREA_OFFSET(bl2_rotpk_zero_bits[2]));
613 case PLAT_OTP_ID_NV_COUNTER_BL2_3:
614 return otp_write(USER_AREA_OFFSET(bl2_nv_counter[3]),
615 USER_AREA_SIZE(bl2_nv_counter[3]), in_len, in, 0);
616
617 case PLAT_OTP_ID_NV_COUNTER_NS_0:
618 return otp_write(USER_AREA_OFFSET(host_nv_counter[0]),
619 USER_AREA_SIZE(host_nv_counter[0]), in_len, in, 0);
620 case PLAT_OTP_ID_NV_COUNTER_NS_1:
621 return otp_write(USER_AREA_OFFSET(host_nv_counter[1]),
622 USER_AREA_SIZE(host_nv_counter[1]), in_len, in, 0);
623 case PLAT_OTP_ID_NV_COUNTER_NS_2:
624 return otp_write(USER_AREA_OFFSET(host_nv_counter[2]),
625 USER_AREA_SIZE(host_nv_counter[2]), in_len, in, 0);
626
627 #ifdef BL1
628 case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
629 return otp_write(USER_AREA_OFFSET(bl2_encryption_key),
630 USER_AREA_SIZE(bl2_encryption_key), in_len, in,
631 USER_AREA_OFFSET(bl2_encryption_key_zero_bits));
632 case PLAT_OTP_ID_BL1_2_IMAGE_HASH:
633 return otp_write(USER_AREA_OFFSET(bl1_2_image_hash),
634 USER_AREA_SIZE(bl1_2_image_hash), in_len, in,
635 USER_AREA_OFFSET(bl1_2_image_hash_zero_bits));
636 case PLAT_OTP_ID_BL2_IMAGE_HASH:
637 return otp_write(USER_AREA_OFFSET(bl2_image_hash),
638 USER_AREA_SIZE(bl2_image_hash), in_len, in,
639 USER_AREA_OFFSET(bl2_image_hash_zero_bits));
640 case PLAT_OTP_ID_NV_COUNTER_BL1_0:
641 return otp_write(USER_AREA_OFFSET(bl1_nv_counter),
642 USER_AREA_SIZE(bl1_nv_counter), in_len, in, 0);
643 case PLAT_OTP_ID_BL1_ROTPK_0:
644 return otp_write(USER_AREA_OFFSET(bl1_rotpk_0),
645 USER_AREA_SIZE(bl1_rotpk_0), in_len, in,
646 USER_AREA_OFFSET(bl1_rotpk_0_zero_bits));
647 case PLAT_OTP_ID_BL1_2_IMAGE:
648 return otp_write(USER_AREA_OFFSET(bl1_2_image),
649 USER_AREA_SIZE(bl1_2_image), in_len, in, 0);
650 #endif /* BL1 */
651
652 case PLAT_OTP_ID_ENTROPY_SEED:
653 return TFM_PLAT_ERR_UNSUPPORTED;
654
655 case PLAT_OTP_ID_SECURE_DEBUG_PK:
656 return otp_write(USER_AREA_OFFSET(secure_debug_pk),
657 USER_AREA_SIZE(secure_debug_pk), in_len, in,
658 USER_AREA_OFFSET(secure_debug_pk_zero_bits));
659
660 case PLAT_OTP_ID_HOST_ROTPK_S:
661 return otp_write(USER_AREA_OFFSET(host_rotpk_s),
662 USER_AREA_SIZE(host_rotpk_s), in_len, in,
663 USER_AREA_OFFSET(host_rotpk_s_zero_bits));
664 case PLAT_OTP_ID_HOST_ROTPK_NS:
665 return otp_write(USER_AREA_OFFSET(host_rotpk_ns),
666 USER_AREA_SIZE(host_rotpk_ns), in_len, in,
667 USER_AREA_OFFSET(host_rotpk_ns_zero_bits));
668 case PLAT_OTP_ID_HOST_ROTPK_CCA:
669 return otp_write(USER_AREA_OFFSET(host_rotpk_cca),
670 USER_AREA_SIZE(host_rotpk_cca), in_len, in,
671 USER_AREA_OFFSET(host_rotpk_cca_zero_bits));
672
673 case PLAT_OTP_ID_CCA_SYSTEM_PROPERTIES:
674 return otp_write(USER_AREA_OFFSET(cca_system_properties),
675 USER_AREA_SIZE(cca_system_properties), in_len, in,
676 USER_AREA_OFFSET(cca_system_properties_zero_bits));
677
678 default:
679 return TFM_PLAT_ERR_UNSUPPORTED;
680 }
681 }
682
683
tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,size_t * size)684 enum tfm_plat_err_t tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,
685 size_t *size)
686 {
687 switch (id) {
688 case PLAT_OTP_ID_HUK:
689 *size = OTP_SIZE(huk);
690 break;
691 case PLAT_OTP_ID_GUK:
692 *size = OTP_SIZE(guk);
693 break;
694
695 case PLAT_OTP_ID_BOOT_SEED:
696 *size = USER_AREA_SIZE(boot_seed);
697 break;
698 case PLAT_OTP_ID_LCS:
699 *size = sizeof(uint32_t);
700 break;
701 case PLAT_OTP_ID_IMPLEMENTATION_ID:
702 *size = USER_AREA_SIZE(implementation_id);
703 break;
704 case PLAT_OTP_ID_CERT_REF:
705 *size = USER_AREA_SIZE(cert_ref);
706 break;
707 case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
708 *size = USER_AREA_SIZE(verification_service_url);
709 break;
710 case PLAT_OTP_ID_PROFILE_DEFINITION:
711 *size = USER_AREA_SIZE(profile_definition);
712 break;
713
714 case PLAT_OTP_ID_BL2_ROTPK_0:
715 *size = OTP_SIZE(rotpk);
716 break;
717 case PLAT_OTP_ID_NV_COUNTER_BL2_0:
718 *size = USER_AREA_SIZE(bl2_nv_counter[0]);
719 break;
720
721 case PLAT_OTP_ID_BL2_ROTPK_1:
722 *size = USER_AREA_SIZE(bl2_rotpk[0]);
723 break;
724 case PLAT_OTP_ID_NV_COUNTER_BL2_1:
725 *size = USER_AREA_SIZE(bl2_nv_counter[1]);
726 break;
727
728 case PLAT_OTP_ID_BL2_ROTPK_2:
729 *size = USER_AREA_SIZE(bl2_rotpk[1]);
730 break;
731 case PLAT_OTP_ID_NV_COUNTER_BL2_2:
732 *size = USER_AREA_SIZE(bl2_nv_counter[2]);
733 break;
734
735 case PLAT_OTP_ID_BL2_ROTPK_3:
736 *size = USER_AREA_SIZE(bl2_rotpk[2]);
737 break;
738 case PLAT_OTP_ID_NV_COUNTER_BL2_3:
739 *size = USER_AREA_SIZE(bl2_nv_counter[3]);
740 break;
741
742 case PLAT_OTP_ID_NV_COUNTER_NS_0:
743 *size = USER_AREA_SIZE(host_nv_counter[0]);
744 break;
745 case PLAT_OTP_ID_NV_COUNTER_NS_1:
746 *size = USER_AREA_SIZE(host_nv_counter[1]);
747 break;
748 case PLAT_OTP_ID_NV_COUNTER_NS_2:
749 *size = USER_AREA_SIZE(host_nv_counter[2]);
750 break;
751
752 #ifdef BL1
753 case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
754 *size = USER_AREA_SIZE(bl2_encryption_key);
755 break;
756 case PLAT_OTP_ID_BL1_2_IMAGE_HASH:
757 *size = USER_AREA_SIZE(bl1_2_image_hash);
758 break;
759 case PLAT_OTP_ID_BL2_IMAGE_HASH:
760 *size = USER_AREA_SIZE(bl2_image_hash);
761 break;
762 case PLAT_OTP_ID_NV_COUNTER_BL1_0:
763 *size = USER_AREA_SIZE(bl1_nv_counter);
764 break;
765 case PLAT_OTP_ID_BL1_ROTPK_0:
766 *size = USER_AREA_SIZE(bl1_rotpk_0);
767 break;
768 case PLAT_OTP_ID_BL1_2_IMAGE:
769 *size = USER_AREA_SIZE(bl1_2_image);
770 break;
771 #endif
772
773 case PLAT_OTP_ID_ENTROPY_SEED:
774 return TFM_PLAT_ERR_UNSUPPORTED;
775
776 case PLAT_OTP_ID_SECURE_DEBUG_PK:
777 *size = USER_AREA_SIZE(secure_debug_pk);
778 break;
779
780 case PLAT_OTP_ID_HOST_ROTPK_S:
781 *size = USER_AREA_SIZE(host_rotpk_s);
782 break;
783 case PLAT_OTP_ID_HOST_ROTPK_NS:
784 *size = USER_AREA_SIZE(host_rotpk_ns);
785 break;
786 case PLAT_OTP_ID_HOST_ROTPK_CCA:
787 *size = USER_AREA_SIZE(host_rotpk_cca);
788 break;
789
790 case PLAT_OTP_ID_CCA_SYSTEM_PROPERTIES:
791 *size = USER_AREA_SIZE(cca_system_properties);
792 break;
793
794 default:
795 return TFM_PLAT_ERR_UNSUPPORTED;
796 }
797
798 return TFM_PLAT_ERR_SUCCESS;
799 }
800