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