1 /*
2  * Copyright (c) 2021-2024, 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 "tfm_hal_device_header.h"
15 #include "uart_stdout.h"
16 #include "tfm_hal_platform.h"
17 #include "rse_memory_sizes.h"
18 #ifdef RSE_ENCRYPTED_OTP_KEYS
19 #include "cc3xx_drv.h"
20 #include "kmu_drv.h"
21 #endif /* RSE_ENCRYPTED_OTP_KEYS */
22 #ifdef RSE_BRINGUP_OTP_EMULATION
23 #include "rse_otp_emulation.h"
24 #endif /* RSE_BRINGUP_OTP_EMULATION */
25 
26 #ifdef MCUBOOT_SIGN_EC384
27 /* The sizes are in 4 byte words */
28 #define BL2_ROTPK_HASH_SIZE (12)
29 #define BL2_ROTPK_SIZE      (25)
30 #else
31 #define BL2_ROTPK_HASH_SIZE (8)
32 #define BL2_ROTPK_SIZE      (17)
33 #endif /* MCUBOOT_SIGN_EC384 */
34 
35 #ifdef MCUBOOT_BUILTIN_KEY
36 #define PROV_ROTPK_DATA_SIZE    BL2_ROTPK_SIZE
37 #else
38 #define PROV_ROTPK_DATA_SIZE    BL2_ROTPK_HASH_SIZE
39 #endif /* MCUBOOT_BUILTIN_KEY */
40 
41 
42 #define OTP_OFFSET(x)        (offsetof(struct lcm_otp_layout_t, x))
43 #define OTP_SIZE(x)          (sizeof(((struct lcm_otp_layout_t *)0)->x))
44 #define USER_AREA_OFFSET(x)  (OTP_OFFSET(user_data) + \
45                               offsetof(struct plat_user_area_layout_t, x))
46 #define USER_AREA_SIZE(x)    (sizeof(((struct plat_user_area_layout_t *)0)->x))
47 
48 #define OTP_ADDRESS(x)       ((LCM_BASE_S) + 0x1000 + OTP_OFFSET(x))
49 #define USER_AREA_ADDRESS(x) ((LCM_BASE_S) + 0x1000 + USER_AREA_OFFSET(x))
50 
51 #define OTP_ROM_ENCRYPTION_KEY KMU_HW_SLOT_KCE_CM
52 #define OTP_RUNTIME_ENCRYPTION_KEY KMU_HW_SLOT_KCE_DM
53 
54 #ifndef RSE_HAS_MANUFACTURING_DATA
55 #undef OTP_MANUFACTURING_DATA_MAX_SIZE
56 #define OTP_MANUFACTURING_DATA_MAX_SIZE 0
57 #endif /* !RSE_HAS_MANUFACTURING_DATA */
58 
59 __PACKED_STRUCT plat_user_area_layout_t {
60     __PACKED_UNION {
61         __PACKED_STRUCT {
62             uint64_t cm_locked_size;
63             uint32_t cm_locked_size_zero_count;
64             uint32_t cm_zero_count;
65 
66             uint64_t dm_locked_size;
67             uint32_t dm_locked_size_zero_count;
68             uint32_t dm_zero_count;
69 
70             __PACKED_STRUCT {
71                 uint32_t bl1_2_image_len;
72 
73             /* Things after this point are not touched by BL1_1, and hence are
74              * modifiable by new provisioning code.
75              */
76                 uint32_t cca_system_properties;
77 
78                 uint32_t cm_config_flags;
79                 uint32_t _pad0;
80             } cm_locked;
81 
82             __PACKED_STRUCT {
83                 uint32_t bl1_rotpk_0[14];
84 
85                 uint32_t bl2_rotpk[MCUBOOT_IMAGE_NUMBER][PROV_ROTPK_DATA_SIZE];
86 
87                 uint32_t iak_len;
88                 uint32_t iak_type;
89                 uint32_t iak_id[8];
90                 uint32_t implementation_id[8];
91                 uint32_t verification_service_url[8];
92                 uint32_t profile_definition[8];
93 
94                 uint32_t secure_debug_pk[8];
95 
96                 uint32_t host_rotpk_s[24];
97                 uint32_t host_rotpk_ns[24];
98                 uint32_t host_rotpk_cca[24];
99 
100                 uint32_t dm_config_flags;
101 
102                 uint32_t rse_id;
103 #if RSE_AMOUNT > 1
104                 uint32_t rse_to_rse_sender_routing_table[RSE_AMOUNT];
105                 uint32_t rse_to_rse_receiver_routing_table[RSE_AMOUNT];
106 #endif /* RSE_AMOUNT > 1 */
107 
108                 __PACKED_STRUCT {
109                     uint32_t bl2_encryption_key[8];
110                     uint32_t s_image_encryption_key[8];
111                     uint32_t ns_image_encryption_key[8];
112 #if LCM_VERSION == 0
113                     uint32_t runtime_otp_encryption_key[8];
114 #endif /* LCM_VERSION == 0 */
115                 } dm_encrypted;
116             } dm_locked;
117 
118             __PACKED_STRUCT {
119                 uint32_t bl1_nv_counter[16];
120                 uint32_t bl2_nv_counter[MCUBOOT_IMAGE_NUMBER][16];
121 #ifdef PLATFORM_HAS_PS_NV_OTP_COUNTERS
122                 uint32_t ps_nv_counter[3][16];
123 #endif /* PLATFORM_HAS_PS_NV_OTP_COUNTERS */
124                 uint32_t host_nv_counter[3][16];
125                 uint32_t reprovisioning_bits;
126             } unlocked_area;
127         };
128         uint8_t _pad0[OTP_TOTAL_SIZE - OTP_DMA_ICS_SIZE - BL1_2_CODE_SIZE
129                       - OTP_MANUFACTURING_DATA_MAX_SIZE - sizeof(struct lcm_otp_layout_t)];
130     };
131 
132     uint32_t bl1_2_image[BL1_2_CODE_SIZE / sizeof(uint32_t)];
133 
134 #ifdef RSE_HAS_MANUFACTURING_DATA
135     __PACKED_STRUCT {
136         uint32_t data[(OTP_MANUFACTURING_DATA_MAX_SIZE - 4 * sizeof(uint32_t)) / sizeof(uint32_t)];
137         /* Things before this point are not touched by BL1_1, and hence are
138          * modifiable by new provisioning code. Things after this point have
139          * fixed addresses which are used by BL1_1 and cannot be changed by
140          * new provisioning code.
141          */
142         __PACKED_STRUCT {
143             uint32_t _pad0;
144             uint32_t size;
145             uint32_t _pad1;
146             uint32_t zero_count;
147         } header;
148     } manufacturing_data;
149 #endif /* RSE_HAS_MANUFACTURING_DATA */
150 
151     __PACKED_UNION {
152         __PACKED_STRUCT {
153             uint32_t crc;
154             uint32_t dma_commands[];
155         };
156         uint8_t _pad2[OTP_DMA_ICS_SIZE];
157     } dma_initial_command_sequence;
158 };
159 
160 static const uint16_t otp_offsets[PLAT_OTP_ID_MAX] = {
161     [PLAT_OTP_ID_HUK] = OTP_OFFSET(huk),
162     [PLAT_OTP_ID_GUK] = OTP_OFFSET(guk),
163 
164     [PLAT_OTP_ID_IAK_LEN] = USER_AREA_OFFSET(dm_locked.iak_len),
165     [PLAT_OTP_ID_IAK_TYPE] = USER_AREA_OFFSET(dm_locked.iak_type),
166     [PLAT_OTP_ID_IAK_ID] = USER_AREA_OFFSET(dm_locked.iak_id),
167 
168     [PLAT_OTP_ID_IMPLEMENTATION_ID] = USER_AREA_OFFSET(dm_locked.implementation_id),
169     [PLAT_OTP_ID_VERIFICATION_SERVICE_URL] = USER_AREA_OFFSET(dm_locked.verification_service_url),
170     [PLAT_OTP_ID_PROFILE_DEFINITION] = USER_AREA_OFFSET(dm_locked.profile_definition),
171 
172     [PLAT_OTP_ID_BL2_ROTPK_0] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[0]),
173 #if (MCUBOOT_IMAGE_NUMBER > 1)
174     [PLAT_OTP_ID_BL2_ROTPK_1] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[1]),
175 #endif
176 #if (MCUBOOT_IMAGE_NUMBER > 2)
177     [PLAT_OTP_ID_BL2_ROTPK_2] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[2]),
178 #endif
179 #if (MCUBOOT_IMAGE_NUMBER > 3)
180     [PLAT_OTP_ID_BL2_ROTPK_3] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[3]),
181 #endif
182 #if (MCUBOOT_IMAGE_NUMBER > 4)
183     [PLAT_OTP_ID_BL2_ROTPK_4] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[4]),
184 #endif
185 #if (MCUBOOT_IMAGE_NUMBER > 5)
186     [PLAT_OTP_ID_BL2_ROTPK_5] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[5]),
187 #endif
188 #if (MCUBOOT_IMAGE_NUMBER > 6)
189     [PLAT_OTP_ID_BL2_ROTPK_6] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[6]),
190 #endif
191 #if (MCUBOOT_IMAGE_NUMBER > 7)
192     [PLAT_OTP_ID_BL2_ROTPK_7] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[7]),
193 #endif
194 #if (MCUBOOT_IMAGE_NUMBER > 8)
195     [PLAT_OTP_ID_BL2_ROTPK_8] = USER_AREA_OFFSET(dm_locked.bl2_rotpk[8]),
196 #endif
197 
198     [PLAT_OTP_ID_NV_COUNTER_BL2_0] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[0]),
199 #if (MCUBOOT_IMAGE_NUMBER > 1)
200     [PLAT_OTP_ID_NV_COUNTER_BL2_1] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[1]),
201 #endif
202 #if (MCUBOOT_IMAGE_NUMBER > 2)
203     [PLAT_OTP_ID_NV_COUNTER_BL2_2] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[2]),
204 #endif
205 #if (MCUBOOT_IMAGE_NUMBER > 3)
206     [PLAT_OTP_ID_NV_COUNTER_BL2_3] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[3]),
207 #endif
208 #if (MCUBOOT_IMAGE_NUMBER > 4)
209     [PLAT_OTP_ID_NV_COUNTER_BL2_4] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[4]),
210 #endif
211 #if (MCUBOOT_IMAGE_NUMBER > 5)
212     [PLAT_OTP_ID_NV_COUNTER_BL2_5] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[5]),
213 #endif
214 #if (MCUBOOT_IMAGE_NUMBER > 6)
215     [PLAT_OTP_ID_NV_COUNTER_BL2_6] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[6]),
216 #endif
217 #if (MCUBOOT_IMAGE_NUMBER > 7)
218     [PLAT_OTP_ID_NV_COUNTER_BL2_7] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[7]),
219 #endif
220 #if (MCUBOOT_IMAGE_NUMBER > 8)
221     [PLAT_OTP_ID_NV_COUNTER_BL2_8] = USER_AREA_OFFSET(unlocked_area.bl2_nv_counter[8]),
222 #endif
223 
224 #ifdef PLATFORM_HAS_PS_NV_OTP_COUNTERS
225     [PLAT_OTP_ID_NV_COUNTER_PS_0] = USER_AREA_OFFSET(unlocked_area.ps_nv_counter[0]),
226     [PLAT_OTP_ID_NV_COUNTER_PS_1] = USER_AREA_OFFSET(unlocked_area.ps_nv_counter[1]),
227     [PLAT_OTP_ID_NV_COUNTER_PS_2] = USER_AREA_OFFSET(unlocked_area.ps_nv_counter[2]),
228 #endif /* PLATFORM_HAS_PS_NV_OTP_COUNTERS */
229 
230     [PLAT_OTP_ID_NV_COUNTER_NS_0] = USER_AREA_OFFSET(unlocked_area.host_nv_counter[0]),
231     [PLAT_OTP_ID_NV_COUNTER_NS_1] = USER_AREA_OFFSET(unlocked_area.host_nv_counter[1]),
232     [PLAT_OTP_ID_NV_COUNTER_NS_2] = USER_AREA_OFFSET(unlocked_area.host_nv_counter[2]),
233 
234     [PLAT_OTP_ID_KEY_BL2_ENCRYPTION] = USER_AREA_OFFSET(dm_locked.dm_encrypted.bl2_encryption_key),
235     [PLAT_OTP_ID_KEY_SECURE_ENCRYPTION] = USER_AREA_OFFSET(dm_locked.dm_encrypted.s_image_encryption_key),
236     [PLAT_OTP_ID_KEY_NON_SECURE_ENCRYPTION] = USER_AREA_OFFSET(dm_locked.dm_encrypted.ns_image_encryption_key),
237 
238     [PLAT_OTP_ID_BL1_2_IMAGE_LEN] = USER_AREA_OFFSET(cm_locked.bl1_2_image_len),
239     [PLAT_OTP_ID_BL1_2_IMAGE_HASH] = OTP_OFFSET(rotpk),
240     [PLAT_OTP_ID_BL1_ROTPK_0] = USER_AREA_OFFSET(dm_locked.bl1_rotpk_0),
241 
242     [PLAT_OTP_ID_NV_COUNTER_BL1_0] = USER_AREA_OFFSET(unlocked_area.bl1_nv_counter),
243 
244     [PLAT_OTP_ID_SECURE_DEBUG_PK] = USER_AREA_OFFSET(dm_locked.secure_debug_pk),
245 
246     [PLAT_OTP_ID_HOST_ROTPK_S] = USER_AREA_OFFSET(dm_locked.host_rotpk_s),
247     [PLAT_OTP_ID_HOST_ROTPK_NS] = USER_AREA_OFFSET(dm_locked.host_rotpk_ns),
248     [PLAT_OTP_ID_HOST_ROTPK_CCA] = USER_AREA_OFFSET(dm_locked.host_rotpk_cca),
249 
250     [PLAT_OTP_ID_CCA_SYSTEM_PROPERTIES] = USER_AREA_OFFSET(cm_locked.cca_system_properties),
251 
252     [PLAT_OTP_ID_REPROVISIONING_BITS] = USER_AREA_OFFSET(unlocked_area.reprovisioning_bits),
253     [PLAT_OTP_ID_RSE_ID] = USER_AREA_OFFSET(dm_locked.rse_id),
254 
255     [PLAT_OTP_ID_DMA_ICS] = USER_AREA_OFFSET(dma_initial_command_sequence),
256 
257 #ifdef RSE_HAS_MANUFACTURING_DATA
258     [PLAT_OTP_ID_MANUFACTURING_DATA_LEN] = USER_AREA_OFFSET(manufacturing_data.header.size),
259 #endif /* RSE_HAS_MANUFACTURING_DATA */
260 
261     [PLAT_OTP_ID_ROM_OTP_ENCRYPTION_KEY] = OTP_OFFSET(kce_cm),
262 #if LCM_VERSION == 0
263     [PLAT_OTP_ID_RUNTIME_OTP_ENCRYPTION_KEY] = USER_AREA_OFFSET(dm_locked.dm_encrypted.runtime_otp_encryption_key),
264 #else
265     [PLAT_OTP_ID_RUNTIME_OTP_ENCRYPTION_KEY] = OTP_OFFSET(kce_dm),
266 #endif
267 
268     [PLAT_OTP_ID_CM_CONFIG_FLAGS] = USER_AREA_OFFSET(cm_locked.cm_config_flags),
269     [PLAT_OTP_ID_DM_CONFIG_FLAGS] = USER_AREA_OFFSET(dm_locked.dm_config_flags),
270 
271 #if RSE_AMOUNT > 1
272     [PLAT_OTP_ID_RSE_TO_RSE_SENDER_ROUTING_TABLE] = USER_AREA_OFFSET(dm_locked.rse_to_rse_sender_routing_table),
273     [PLAT_OTP_ID_RSE_TO_RSE_RECEIVER_ROUTING_TABLE] = USER_AREA_OFFSET(dm_locked.rse_to_rse_receiver_routing_table),
274 #endif /* RSE_AMOUNT > 1 */
275 };
276 
277 static const uint16_t otp_sizes[PLAT_OTP_ID_MAX] = {
278     [PLAT_OTP_ID_HUK] = OTP_SIZE(huk),
279     [PLAT_OTP_ID_GUK] = OTP_SIZE(guk),
280 
281     [PLAT_OTP_ID_LCS] = sizeof(uint32_t),
282 
283     [PLAT_OTP_ID_IAK_LEN] = USER_AREA_SIZE(dm_locked.iak_len),
284     [PLAT_OTP_ID_IAK_TYPE] = USER_AREA_SIZE(dm_locked.iak_type),
285     [PLAT_OTP_ID_IAK_ID] = USER_AREA_SIZE(dm_locked.iak_id),
286 
287     [PLAT_OTP_ID_IMPLEMENTATION_ID] = USER_AREA_SIZE(dm_locked.implementation_id),
288     [PLAT_OTP_ID_VERIFICATION_SERVICE_URL] = USER_AREA_SIZE(dm_locked.verification_service_url),
289     [PLAT_OTP_ID_PROFILE_DEFINITION] = USER_AREA_SIZE(dm_locked.profile_definition),
290 
291     [PLAT_OTP_ID_BL2_ROTPK_0] = USER_AREA_SIZE(dm_locked.bl2_rotpk[0]),
292 #if (MCUBOOT_IMAGE_NUMBER > 1)
293     [PLAT_OTP_ID_BL2_ROTPK_1] = USER_AREA_SIZE(dm_locked.bl2_rotpk[1]),
294 #endif
295 #if (MCUBOOT_IMAGE_NUMBER > 2)
296     [PLAT_OTP_ID_BL2_ROTPK_2] = USER_AREA_SIZE(dm_locked.bl2_rotpk[2]),
297 #endif
298 #if (MCUBOOT_IMAGE_NUMBER > 3)
299     [PLAT_OTP_ID_BL2_ROTPK_3] = USER_AREA_SIZE(dm_locked.bl2_rotpk[3]),
300 #endif
301 #if (MCUBOOT_IMAGE_NUMBER > 4)
302     [PLAT_OTP_ID_BL2_ROTPK_4] = USER_AREA_SIZE(dm_locked.bl2_rotpk[4]),
303 #endif
304 #if (MCUBOOT_IMAGE_NUMBER > 5)
305     [PLAT_OTP_ID_BL2_ROTPK_5] = USER_AREA_SIZE(dm_locked.bl2_rotpk[5]),
306 #endif
307 #if (MCUBOOT_IMAGE_NUMBER > 6)
308     [PLAT_OTP_ID_BL2_ROTPK_6] = USER_AREA_SIZE(dm_locked.bl2_rotpk[6]),
309 #endif
310 #if (MCUBOOT_IMAGE_NUMBER > 7)
311     [PLAT_OTP_ID_BL2_ROTPK_7] = USER_AREA_SIZE(dm_locked.bl2_rotpk[7]),
312 #endif
313 #if (MCUBOOT_IMAGE_NUMBER > 8)
314     [PLAT_OTP_ID_BL2_ROTPK_8] = USER_AREA_SIZE(dm_locked.bl2_rotpk[8]),
315 #endif
316 
317     [PLAT_OTP_ID_NV_COUNTER_BL2_0] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[0]),
318 #if (MCUBOOT_IMAGE_NUMBER > 1)
319     [PLAT_OTP_ID_NV_COUNTER_BL2_1] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[1]),
320 #endif
321 #if (MCUBOOT_IMAGE_NUMBER > 2)
322     [PLAT_OTP_ID_NV_COUNTER_BL2_2] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[2]),
323 #endif
324 #if (MCUBOOT_IMAGE_NUMBER > 3)
325     [PLAT_OTP_ID_NV_COUNTER_BL2_3] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[3]),
326 #endif
327 #if (MCUBOOT_IMAGE_NUMBER > 4)
328     [PLAT_OTP_ID_NV_COUNTER_BL2_4] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[4]),
329 #endif
330 #if (MCUBOOT_IMAGE_NUMBER > 5)
331     [PLAT_OTP_ID_NV_COUNTER_BL2_5] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[5]),
332 #endif
333 #if (MCUBOOT_IMAGE_NUMBER > 6)
334     [PLAT_OTP_ID_NV_COUNTER_BL2_6] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[6]),
335 #endif
336 #if (MCUBOOT_IMAGE_NUMBER > 7)
337     [PLAT_OTP_ID_NV_COUNTER_BL2_7] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[7]),
338 #endif
339 #if (MCUBOOT_IMAGE_NUMBER > 8)
340     [PLAT_OTP_ID_NV_COUNTER_BL2_8] = USER_AREA_SIZE(unlocked_area.bl2_nv_counter[8]),
341 #endif
342 
343 #ifdef PLATFORM_HAS_PS_NV_OTP_COUNTERS
344     [PLAT_OTP_ID_NV_COUNTER_PS_0] = USER_AREA_SIZE(unlocked_area.ps_nv_counter[0]),
345     [PLAT_OTP_ID_NV_COUNTER_PS_1] = USER_AREA_SIZE(unlocked_area.ps_nv_counter[1]),
346     [PLAT_OTP_ID_NV_COUNTER_PS_2] = USER_AREA_SIZE(unlocked_area.ps_nv_counter[2]),
347 #endif /* PLATFORM_HAS_PS_NV_OTP_COUNTERS */
348 
349     [PLAT_OTP_ID_NV_COUNTER_NS_0] = USER_AREA_SIZE(unlocked_area.host_nv_counter[0]),
350     [PLAT_OTP_ID_NV_COUNTER_NS_1] = USER_AREA_SIZE(unlocked_area.host_nv_counter[1]),
351     [PLAT_OTP_ID_NV_COUNTER_NS_2] = USER_AREA_SIZE(unlocked_area.host_nv_counter[2]),
352 
353     [PLAT_OTP_ID_KEY_BL2_ENCRYPTION] = USER_AREA_SIZE(dm_locked.dm_encrypted.bl2_encryption_key),
354     [PLAT_OTP_ID_KEY_SECURE_ENCRYPTION] = USER_AREA_SIZE(dm_locked.dm_encrypted.s_image_encryption_key),
355     [PLAT_OTP_ID_KEY_NON_SECURE_ENCRYPTION] = USER_AREA_SIZE(dm_locked.dm_encrypted.ns_image_encryption_key),
356 
357     [PLAT_OTP_ID_BL1_2_IMAGE] = USER_AREA_SIZE(bl1_2_image),
358     [PLAT_OTP_ID_BL1_2_IMAGE_LEN] = USER_AREA_SIZE(cm_locked.bl1_2_image_len),
359     [PLAT_OTP_ID_BL1_2_IMAGE_HASH] = OTP_SIZE(rotpk),
360     [PLAT_OTP_ID_BL1_ROTPK_0] = USER_AREA_SIZE(dm_locked.bl1_rotpk_0),
361 
362     [PLAT_OTP_ID_NV_COUNTER_BL1_0] = USER_AREA_SIZE(unlocked_area.bl1_nv_counter),
363 
364     [PLAT_OTP_ID_SECURE_DEBUG_PK] = USER_AREA_SIZE(dm_locked.secure_debug_pk),
365 
366     [PLAT_OTP_ID_HOST_ROTPK_S] = USER_AREA_SIZE(dm_locked.host_rotpk_s),
367     [PLAT_OTP_ID_HOST_ROTPK_NS] = USER_AREA_SIZE(dm_locked.host_rotpk_ns),
368     [PLAT_OTP_ID_HOST_ROTPK_CCA] = USER_AREA_SIZE(dm_locked.host_rotpk_cca),
369 
370     [PLAT_OTP_ID_CCA_SYSTEM_PROPERTIES] = USER_AREA_SIZE(cm_locked.cca_system_properties),
371 
372     [PLAT_OTP_ID_REPROVISIONING_BITS] = USER_AREA_SIZE(unlocked_area.reprovisioning_bits),
373     [PLAT_OTP_ID_RSE_ID] = USER_AREA_SIZE(dm_locked.rse_id),
374 
375     [PLAT_OTP_ID_DMA_ICS] = USER_AREA_SIZE(dma_initial_command_sequence),
376 
377 #ifdef RSE_HAS_MANUFACTURING_DATA
378     [PLAT_OTP_ID_MANUFACTURING_DATA_LEN] = USER_AREA_SIZE(manufacturing_data.header.size),
379 #endif /* RSE_HAS_MANUFACTURING_DATA */
380 
381     [PLAT_OTP_ID_ROM_OTP_ENCRYPTION_KEY] = OTP_SIZE(kce_cm),
382 #if LCM_VERSION == 0
383     [PLAT_OTP_ID_RUNTIME_OTP_ENCRYPTION_KEY] = USER_AREA_SIZE(dm_locked.dm_encrypted.runtime_otp_encryption_key),
384 #else
385     [PLAT_OTP_ID_RUNTIME_OTP_ENCRYPTION_KEY] = OTP_SIZE(kce_dm),
386 #endif
387 
388     [PLAT_OTP_ID_CM_CONFIG_FLAGS] = USER_AREA_SIZE(cm_locked.cm_config_flags),
389     [PLAT_OTP_ID_DM_CONFIG_FLAGS] = USER_AREA_SIZE(dm_locked.dm_config_flags),
390 
391 #if RSE_AMOUNT > 1
392     [PLAT_OTP_ID_RSE_TO_RSE_SENDER_ROUTING_TABLE] = USER_AREA_SIZE(dm_locked.rse_to_rse_sender_routing_table),
393     [PLAT_OTP_ID_RSE_TO_RSE_RECEIVER_ROUTING_TABLE] = USER_AREA_SIZE(dm_locked.rse_to_rse_receiver_routing_table),
394 #endif /* RSE_AMOUNT > 1 */
395 };
396 
397 #ifdef RSE_BRINGUP_OTP_EMULATION
check_if_otp_is_emulated(uint32_t offset,uint32_t len)398 static enum tfm_plat_err_t check_if_otp_is_emulated(uint32_t offset, uint32_t len)
399 {
400     enum lcm_error_t lcm_err;
401     enum lcm_tp_mode_t tp_mode;
402 
403     lcm_err = lcm_get_tp_mode(&LCM_DEV_S, &tp_mode);
404     if (lcm_err != LCM_ERROR_NONE) {
405         return TFM_PLAT_ERR_SYSTEM_ERR;
406     }
407 
408     /* If the OTP is outside the emulated region, and the emulation is enabled,
409      * then return UNSUPPORTED.
410      */
411     if (tp_mode != LCM_TP_MODE_PCI &&
412         rse_otp_emulation_is_enabled() &&
413         offset + len > RSE_BRINGUP_OTP_EMULATION_SIZE) {
414         return TFM_PLAT_ERR_UNSUPPORTED;
415     }
416 
417     return TFM_PLAT_ERR_SUCCESS;
418 }
419 #endif /* RSE_BRINGUP_OTP_EMULATION */
420 
otp_read(uint32_t offset,uint32_t len,uint32_t buf_len,uint8_t * buf)421 static enum tfm_plat_err_t otp_read(uint32_t offset, uint32_t len,
422                                     uint32_t buf_len, uint8_t *buf)
423 {
424     if (len == 0) {
425         return TFM_PLAT_ERR_SUCCESS;
426     }
427 
428     if (offset == 0) {
429         return TFM_PLAT_ERR_UNSUPPORTED;
430     }
431 
432 #ifdef RSE_BRINGUP_OTP_EMULATION
433     enum tfm_plat_err_t plat_err;
434 
435     plat_err = check_if_otp_is_emulated(offset, len);
436     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
437         return plat_err;
438     }
439 #endif /* RSE_BRINGUP_OTP_EMULATION */
440 
441     if (buf_len < len) {
442         len = buf_len;
443     }
444 
445     if (lcm_otp_read(&LCM_DEV_S, offset, len, buf) != LCM_ERROR_NONE) {
446         return TFM_PLAT_ERR_SYSTEM_ERR;
447     } else {
448         return TFM_PLAT_ERR_SUCCESS;
449     }
450 }
451 
otp_read_encrypted(uint32_t offset,uint32_t len,uint32_t buf_len,uint8_t * buf,enum kmu_hardware_keyslot_t key)452 static enum tfm_plat_err_t otp_read_encrypted(uint32_t offset, uint32_t len,
453                                               uint32_t buf_len, uint8_t *buf,
454                                               enum kmu_hardware_keyslot_t key)
455 {
456     if (len == 0) {
457         return TFM_PLAT_ERR_SUCCESS;
458     }
459 
460     if (offset == 0) {
461         return TFM_PLAT_ERR_UNSUPPORTED;
462     }
463 
464 #ifndef RSE_ENCRYPTED_OTP_KEYS
465     return otp_read(offset, len, buf_len, buf);
466 #else
467     /* This is designed for keys, so 32 is a sane limit */
468     uint32_t tmp_buf[32 / sizeof(uint32_t)];
469     uint32_t iv[4] = {offset, 0, 0, 0};
470     cc3xx_err_t cc_err;
471     enum tfm_plat_err_t plat_err;
472 
473 #ifdef RSE_BRINGUP_OTP_EMULATION
474     plat_err = check_if_otp_is_emulated(offset, len);
475     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
476         return plat_err;
477     }
478 #endif /* RSE_BRINGUP_OTP_EMULATION */
479 
480     if (len > sizeof(tmp_buf)) {
481         return TFM_PLAT_ERR_INVALID_INPUT;
482     }
483 
484     plat_err = otp_read(offset, len, sizeof(tmp_buf), (uint8_t *)tmp_buf);
485     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
486         return plat_err;
487     }
488 
489     cc_err = cc3xx_lowlevel_aes_init(CC3XX_AES_DIRECTION_DECRYPT, CC3XX_AES_MODE_CTR,
490                                      KMU_HW_SLOT_KCE_CM, NULL, CC3XX_AES_KEYSIZE_256,
491                                      iv, sizeof(iv));
492     if (cc_err != CC3XX_ERR_SUCCESS) {
493         return TFM_PLAT_ERR_SYSTEM_ERR;
494     }
495 
496     cc3xx_lowlevel_aes_set_output_buffer(buf, buf_len);
497 
498     cc_err = cc3xx_lowlevel_aes_update((uint8_t *)tmp_buf, len);
499     if (cc_err != CC3XX_ERR_SUCCESS) {
500         cc3xx_lowlevel_aes_uninit();
501         return TFM_PLAT_ERR_SYSTEM_ERR;
502     }
503 
504     cc3xx_lowlevel_aes_finish(NULL, NULL);
505 
506     return TFM_PLAT_ERR_SUCCESS;
507 #endif
508 }
509 
otp_write(uint32_t offset,uint32_t len,uint32_t buf_len,const uint8_t * buf)510 static enum tfm_plat_err_t otp_write(uint32_t offset, uint32_t len,
511                                      uint32_t buf_len, const uint8_t *buf)
512 {
513     enum lcm_error_t err;
514 
515     if (buf_len > len) {
516         return TFM_PLAT_ERR_INVALID_INPUT;
517     }
518 
519     err = lcm_otp_write(&LCM_DEV_S, offset, buf_len, buf);
520     if (err != LCM_ERROR_NONE) {
521         return TFM_PLAT_ERR_SYSTEM_ERR;
522     }
523 
524     return TFM_PLAT_ERR_SUCCESS;
525 }
526 
otp_write_encrypted(uint32_t offset,uint32_t len,uint32_t buf_len,const uint8_t * buf,enum kmu_hardware_keyslot_t key)527 static enum tfm_plat_err_t otp_write_encrypted(uint32_t offset, uint32_t len,
528                                      uint32_t buf_len, const uint8_t *buf,
529                                      enum kmu_hardware_keyslot_t key)
530 {
531 #ifndef RSE_ENCRYPTED_OTP_KEYS
532     return otp_write(offset, len, buf_len, buf);
533 #else
534     /* This is designed for keys, so 32 is a sane limit */
535     uint32_t tmp_buf[32 / sizeof(uint32_t)];
536     uint32_t iv[4] = {offset, 0, 0, 0};
537     cc3xx_err_t cc_err;
538     enum tfm_plat_err_t plat_err;
539 
540     if (len > sizeof(tmp_buf)) {
541         return TFM_PLAT_ERR_INVALID_INPUT;
542     }
543 
544     cc_err = cc3xx_lowlevel_aes_init(CC3XX_AES_DIRECTION_ENCRYPT, CC3XX_AES_MODE_CTR,
545                             key, NULL, CC3XX_AES_KEYSIZE_256,
546                             iv, sizeof(iv));
547     if (cc_err != CC3XX_ERR_SUCCESS) {
548         return TFM_PLAT_ERR_SYSTEM_ERR;
549     }
550 
551     cc3xx_lowlevel_aes_set_output_buffer((uint8_t *)tmp_buf, sizeof(tmp_buf));
552 
553     cc_err = cc3xx_lowlevel_aes_update(buf, len);
554     if (cc_err != CC3XX_ERR_SUCCESS) {
555         cc3xx_lowlevel_aes_uninit();
556         return TFM_PLAT_ERR_SYSTEM_ERR;
557     }
558 
559     cc3xx_lowlevel_aes_finish(NULL, NULL);
560 
561     plat_err = otp_write(offset, len, sizeof(tmp_buf), (uint8_t *)tmp_buf);
562     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
563         return plat_err;
564     }
565 
566     cc_err = cc3xx_lowlevel_rng_get_random((uint8_t *)tmp_buf, sizeof(tmp_buf));
567     if (cc_err != CC3XX_ERR_SUCCESS) {
568         return TFM_PLAT_ERR_SYSTEM_ERR;
569     }
570 
571     return TFM_PLAT_ERR_SUCCESS;
572 #endif
573 }
574 
check_keys_for_tampering(enum lcm_lcs_t lcs)575 static enum tfm_plat_err_t check_keys_for_tampering(enum lcm_lcs_t lcs)
576 {
577     enum tfm_plat_err_t err;
578     enum integrity_checker_error_t ic_err;
579 #ifdef RSE_HAS_MANUFACTURING_DATA
580     uint32_t manufacturing_size;
581 #endif /* RSE_HAS_MANUFACTURING_DATA */
582     uint64_t cm_size;
583     uint64_t dm_size;
584 
585 #ifdef RSE_HAS_MANUFACTURING_DATA
586     err = otp_read(USER_AREA_OFFSET(manufacturing_data.header.size),
587                    USER_AREA_SIZE(manufacturing_data.header.size),
588                    sizeof(manufacturing_size), (uint8_t*)&manufacturing_size);
589     if (err == TFM_PLAT_ERR_SUCCESS) {
590         ic_err = integrity_checker_check_value(&INTEGRITY_CHECKER_DEV_S,
591                                                INTEGRITY_CHECKER_MODE_ZERO_COUNT,
592                                                (uint32_t *)(USER_AREA_ADDRESS(manufacturing_data.header) - manufacturing_size),
593                                                manufacturing_size + 2 * sizeof(uint32_t),
594                                                (uint32_t *)USER_AREA_ADDRESS(manufacturing_data.header.zero_count),
595                                                USER_AREA_SIZE(manufacturing_data.header.zero_count));
596         if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
597             return TFM_PLAT_ERR_SYSTEM_ERR;
598         }
599     } else if (err != TFM_PLAT_ERR_UNSUPPORTED) {
600         return err;
601     }
602 #endif /* RSE_HAS_MANUFACTURING_DATA */
603 
604     if (lcs == LCM_LCS_DM || lcs == LCM_LCS_SE) {
605             ic_err = integrity_checker_check_value(&INTEGRITY_CHECKER_DEV_S,
606                                                    INTEGRITY_CHECKER_MODE_ZERO_COUNT,
607                                                    (uint32_t *)USER_AREA_ADDRESS(cm_locked_size),
608                                                    USER_AREA_SIZE(cm_locked_size),
609                                                    (uint32_t *)USER_AREA_ADDRESS(cm_locked_size_zero_count),
610                                                    USER_AREA_SIZE(cm_locked_size_zero_count));
611             if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
612                 return TFM_PLAT_ERR_SYSTEM_ERR;
613             }
614 
615             err = otp_read(USER_AREA_OFFSET(cm_locked_size),
616                            USER_AREA_SIZE(cm_locked_size),
617                            sizeof(cm_size), (uint8_t*)&cm_size);
618             if (err != TFM_PLAT_ERR_SUCCESS) {
619                 return err;
620             }
621 
622             ic_err = integrity_checker_check_value(&INTEGRITY_CHECKER_DEV_S,
623                                                    INTEGRITY_CHECKER_MODE_ZERO_COUNT,
624                                                    (uint32_t *)USER_AREA_ADDRESS(cm_locked),
625                                                    cm_size,
626                                                    (uint32_t *)USER_AREA_ADDRESS(cm_zero_count),
627                                                    USER_AREA_SIZE(cm_zero_count));
628             if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
629                 return TFM_PLAT_ERR_SYSTEM_ERR;
630             }
631     }
632 
633     if (lcs == LCM_LCS_SE) {
634             ic_err = integrity_checker_check_value(&INTEGRITY_CHECKER_DEV_S,
635                                                    INTEGRITY_CHECKER_MODE_ZERO_COUNT,
636                                                    (uint32_t *)USER_AREA_ADDRESS(dm_locked_size),
637                                                    USER_AREA_SIZE(dm_locked_size),
638                                                    (uint32_t *)USER_AREA_ADDRESS(dm_locked_size_zero_count),
639                                                    USER_AREA_SIZE(dm_locked_size_zero_count));
640             if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
641                 return TFM_PLAT_ERR_SYSTEM_ERR;
642             }
643 
644             err = otp_read(USER_AREA_OFFSET(dm_locked_size),
645                            USER_AREA_SIZE(dm_locked_size),
646                            sizeof(dm_size), (uint8_t*)&dm_size);
647             if (err != TFM_PLAT_ERR_SUCCESS) {
648                 return err;
649             }
650 
651             ic_err = integrity_checker_check_value(&INTEGRITY_CHECKER_DEV_S,
652                                                    INTEGRITY_CHECKER_MODE_ZERO_COUNT,
653                                                    (uint32_t *)(USER_AREA_ADDRESS(cm_locked) + cm_size),
654                                                    dm_size,
655                                                    (uint32_t *)USER_AREA_ADDRESS(dm_zero_count),
656                                                    USER_AREA_SIZE(dm_zero_count));
657             if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
658                 return TFM_PLAT_ERR_SYSTEM_ERR;
659             }
660     }
661 
662     return TFM_PLAT_ERR_SUCCESS;
663 }
664 
map_otp_lcs_to_lcm_lcs(enum plat_otp_lcs_t lcs)665 static enum lcm_lcs_t map_otp_lcs_to_lcm_lcs(enum plat_otp_lcs_t lcs)
666 {
667     switch (lcs) {
668     case PLAT_OTP_LCS_ASSEMBLY_AND_TEST:
669         return LCM_LCS_CM;
670     case PLAT_OTP_LCS_PSA_ROT_PROVISIONING:
671         return LCM_LCS_DM;
672     case PLAT_OTP_LCS_SECURED:
673         return LCM_LCS_SE;
674     case PLAT_OTP_LCS_DECOMMISSIONED:
675         return LCM_LCS_RMA;
676     default:
677         return LCM_LCS_INVALID;
678     }
679 }
680 
map_lcm_lcs_to_otp_lcs(enum lcm_lcs_t lcs)681 static enum plat_otp_lcs_t map_lcm_lcs_to_otp_lcs(enum lcm_lcs_t lcs)
682 {
683     switch (lcs) {
684     case LCM_LCS_CM:
685         return PLAT_OTP_LCS_ASSEMBLY_AND_TEST;
686     case LCM_LCS_DM:
687         return PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
688     case LCM_LCS_SE:
689         return PLAT_OTP_LCS_SECURED;
690     case LCM_LCS_RMA:
691         return PLAT_OTP_LCS_DECOMMISSIONED;
692     default:
693         return PLAT_OTP_LCS_UNKNOWN;
694     }
695 }
696 
otp_read_lcs(size_t out_len,uint8_t * out)697 static enum tfm_plat_err_t otp_read_lcs(size_t out_len, uint8_t *out)
698 {
699     enum lcm_lcs_t lcm_lcs;
700     enum plat_otp_lcs_t *lcs = (enum plat_otp_lcs_t*) out;
701 
702     if (lcm_get_lcs(&LCM_DEV_S, &lcm_lcs)) {
703         return TFM_PLAT_ERR_SYSTEM_ERR;
704     }
705 
706     if (out_len != sizeof(uint32_t)) {
707         return TFM_PLAT_ERR_INVALID_INPUT;
708     }
709 
710     *lcs = map_lcm_lcs_to_otp_lcs(lcm_lcs);
711 
712     return TFM_PLAT_ERR_SUCCESS;
713 }
714 
tfm_plat_otp_init(void)715 enum tfm_plat_err_t tfm_plat_otp_init(void)
716 {
717     uint32_t otp_size;
718     enum lcm_error_t err;
719     enum lcm_lcs_t lcs;
720 
721     err = lcm_init(&LCM_DEV_S);
722     if (err != LCM_ERROR_NONE) {
723         return TFM_PLAT_ERR_SYSTEM_ERR;
724     }
725 
726     err = lcm_get_otp_size(&LCM_DEV_S, &otp_size);
727     if (err != LCM_ERROR_NONE) {
728         return TFM_PLAT_ERR_SYSTEM_ERR;
729     }
730     if (otp_size < OTP_OFFSET(user_data) +
731                    sizeof(struct plat_user_area_layout_t)) {
732         return TFM_PLAT_ERR_SYSTEM_ERR;
733     }
734     if (OTP_TOTAL_SIZE < OTP_OFFSET(user_data) +
735                    sizeof(struct plat_user_area_layout_t)) {
736         return TFM_PLAT_ERR_SYSTEM_ERR;
737     }
738 
739 #ifdef RSE_BRINGUP_OTP_EMULATION
740     /* Check that everything inside the main area can be emulated */
741     if (USER_AREA_OFFSET(unlocked_area) + USER_AREA_SIZE(unlocked_area)
742         > RSE_BRINGUP_OTP_EMULATION_SIZE) {
743         return TFM_PLAT_ERR_SYSTEM_ERR;
744     }
745 #endif /* RSE_BRINGUP_OTP_EMULATION */
746 
747     err = lcm_get_lcs(&LCM_DEV_S, &lcs);
748     if (err != LCM_ERROR_NONE) {
749         return TFM_PLAT_ERR_SYSTEM_ERR;
750     }
751 
752     return check_keys_for_tampering(lcs);
753 }
754 
755 #define PLAT_OTP_ID_BL2_ROTPK_MAX PLAT_OTP_ID_BL2_ROTPK_0 + MCUBOOT_IMAGE_NUMBER
756 #define PLAT_OTP_ID_NV_COUNTER_BL2_MAX \
757     PLAT_OTP_ID_NV_COUNTER_BL2_0 + MCUBOOT_IMAGE_NUMBER
758 
tfm_plat_otp_read(enum tfm_otp_element_id_t id,size_t out_len,uint8_t * out)759 enum tfm_plat_err_t tfm_plat_otp_read(enum tfm_otp_element_id_t id,
760                                       size_t out_len, uint8_t *out)
761 {
762     enum tfm_plat_err_t err;
763 #ifdef RSE_HAS_MANUFACTURING_DATA
764     uint32_t manufacturing_data_size;
765 #endif /* RSE_HAS_MANUFACTURING_DATA */
766     size_t bl1_2_size;
767     uint32_t bl1_2_offset;
768 
769     if (id >= PLAT_OTP_ID_MAX) {
770         return TFM_PLAT_ERR_INVALID_INPUT;
771     }
772 
773     if (id >= PLAT_OTP_ID_BL2_ROTPK_MAX && id <= PLAT_OTP_ID_BL2_ROTPK_8) {
774         return TFM_PLAT_ERR_UNSUPPORTED;
775     }
776     if (id >= PLAT_OTP_ID_NV_COUNTER_BL2_MAX && id <= PLAT_OTP_ID_NV_COUNTER_BL2_8) {
777         return TFM_PLAT_ERR_UNSUPPORTED;
778     }
779 
780     switch(id) {
781     case PLAT_OTP_ID_LCS:
782         return otp_read_lcs(out_len, out);
783     case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
784     case PLAT_OTP_ID_KEY_SECURE_ENCRYPTION:
785     case PLAT_OTP_ID_KEY_NON_SECURE_ENCRYPTION:
786         return otp_read_encrypted(otp_offsets[id], otp_sizes[id], out_len, out,
787                                   OTP_ROM_ENCRYPTION_KEY);
788     case PLAT_OTP_ID_BL1_2_IMAGE:
789         err = otp_read(USER_AREA_OFFSET(cm_locked.bl1_2_image_len),
790                        USER_AREA_SIZE(cm_locked.bl1_2_image_len),
791                        sizeof(bl1_2_size), (uint8_t *)&bl1_2_size);
792         if (err != TFM_PLAT_ERR_SUCCESS) {
793             return err;
794         }
795 
796 #ifdef RSE_HAS_MANUFACTURING_DATA
797         err = otp_read(USER_AREA_OFFSET(manufacturing_data.header.size),
798                        USER_AREA_SIZE(manufacturing_data.header.size),
799                        sizeof(manufacturing_data_size), (uint8_t *)&manufacturing_data_size);
800         if (err != TFM_PLAT_ERR_SUCCESS) {
801             return err;
802         }
803         bl1_2_offset = USER_AREA_OFFSET(manufacturing_data.header) - manufacturing_data_size - bl1_2_size;
804 #else
805         bl1_2_offset = USER_AREA_OFFSET(dma_initial_command_sequence) - bl1_2_size;
806 #endif
807 
808         return otp_read(bl1_2_offset,
809                         bl1_2_size,
810                         out_len, out);
811 
812     case PLAT_OTP_ID_MANUFACTURING_DATA:
813 #ifdef RSE_HAS_MANUFACTURING_DATA
814         err = otp_read(USER_AREA_OFFSET(manufacturing_data.header.size),
815                        USER_AREA_SIZE(manufacturing_data.header.size),
816                        sizeof(manufacturing_data_size), (uint8_t *)&manufacturing_data_size);
817         if (err != TFM_PLAT_ERR_SUCCESS) {
818             return err;
819         }
820 
821         return otp_read(USER_AREA_OFFSET(manufacturing_data.header) - manufacturing_data_size,
822                         manufacturing_data_size,
823                         out_len, out);
824 #else
825         return TFM_PLAT_ERR_UNSUPPORTED;
826 #endif
827     default:
828         return otp_read(otp_offsets[id], otp_sizes[id], out_len, out);
829     }
830 }
831 
otp_write_lcs(size_t in_len,const uint8_t * in)832 static enum tfm_plat_err_t otp_write_lcs(size_t in_len, const uint8_t *in)
833 {
834     enum tfm_plat_err_t err;
835     uint32_t lcs;
836     enum lcm_lcs_t new_lcs = map_otp_lcs_to_lcm_lcs(*(uint32_t*)in);
837     enum lcm_error_t lcm_err;
838     uint16_t gppc_val = 0;
839     uint32_t zero_bit_count;
840     uint64_t region_size;
841     enum integrity_checker_error_t ic_err;
842 
843     if (in_len != sizeof(lcs)) {
844         return TFM_PLAT_ERR_INVALID_INPUT;
845     }
846 
847     switch(new_lcs) {
848         case LCM_LCS_DM:
849             /* Write the size of the CM locked area */
850             region_size = USER_AREA_SIZE(cm_locked);
851             err = otp_write(USER_AREA_OFFSET(cm_locked_size),
852                             USER_AREA_SIZE(cm_locked_size),
853                             sizeof(region_size), (uint8_t *)&region_size);
854             if (err != TFM_PLAT_ERR_SUCCESS) {
855                 return err;
856             }
857 
858             /* Write the zero-bit count of the CM locked area size */
859             ic_err = integrity_checker_compute_value(&INTEGRITY_CHECKER_DEV_S,
860                                                      INTEGRITY_CHECKER_MODE_ZERO_COUNT,
861                                                      &region_size,
862                                                      sizeof(region_size),
863                                                      &zero_bit_count,
864                                                      sizeof(zero_bit_count),
865                                                      NULL);
866             if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
867                 return TFM_PLAT_ERR_SYSTEM_ERR;
868             }
869             err = otp_write(USER_AREA_OFFSET(cm_locked_size_zero_count),
870                             USER_AREA_SIZE(cm_locked_size_zero_count),
871                             sizeof(zero_bit_count), (uint8_t *)&zero_bit_count);
872             if (err != TFM_PLAT_ERR_SUCCESS) {
873                 return err;
874             }
875 
876             /* Write the zero-count of the CM locked area */
877             ic_err = integrity_checker_compute_value(&INTEGRITY_CHECKER_DEV_S,
878                                                      INTEGRITY_CHECKER_MODE_ZERO_COUNT,
879                                                      (uint32_t *)USER_AREA_ADDRESS(cm_locked),
880                                                      region_size,
881                                                      &zero_bit_count,
882                                                      sizeof(zero_bit_count),
883                                                      NULL);
884             if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
885                 return TFM_PLAT_ERR_SYSTEM_ERR;
886             }
887             err = otp_write(USER_AREA_OFFSET(cm_zero_count),
888                             USER_AREA_SIZE(cm_zero_count), sizeof(zero_bit_count),
889                             (uint8_t *)&zero_bit_count);
890             if (err != TFM_PLAT_ERR_SUCCESS) {
891                 return err;
892             }
893             break;
894         case LCM_LCS_SE:
895             /* Write the size of the DM locked area */
896             region_size = USER_AREA_SIZE(dm_locked);
897             err = otp_write(USER_AREA_OFFSET(dm_locked_size),
898                             USER_AREA_SIZE(dm_locked_size),
899                             sizeof(region_size), (uint8_t *)&region_size);
900             if (err != TFM_PLAT_ERR_SUCCESS) {
901                 return err;
902             }
903 
904             /* Write the zero-bit count of the DM locked area size */
905             ic_err = integrity_checker_compute_value(&INTEGRITY_CHECKER_DEV_S,
906                                                      INTEGRITY_CHECKER_MODE_ZERO_COUNT,
907                                                      &region_size,
908                                                      sizeof(region_size),
909                                                      &zero_bit_count,
910                                                      sizeof(zero_bit_count),
911                                                      NULL);
912             if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
913                 return TFM_PLAT_ERR_SYSTEM_ERR;
914             }
915             err = otp_write(USER_AREA_OFFSET(dm_locked_size_zero_count),
916                             USER_AREA_SIZE(dm_locked_size_zero_count),
917                             sizeof(zero_bit_count), (uint8_t *)&zero_bit_count);
918             if (err != TFM_PLAT_ERR_SUCCESS) {
919                 return err;
920             }
921 
922             /* Write the zero-count of the DM locked area */
923             ic_err = integrity_checker_compute_value(&INTEGRITY_CHECKER_DEV_S,
924                                                      INTEGRITY_CHECKER_MODE_ZERO_COUNT,
925                                                      (uint32_t *)USER_AREA_ADDRESS(dm_locked),
926                                                      region_size,
927                                                      &zero_bit_count,
928                                                      sizeof(zero_bit_count),
929                                                      NULL);
930             if (ic_err != INTEGRITY_CHECKER_ERROR_NONE) {
931                 return TFM_PLAT_ERR_SYSTEM_ERR;
932             }
933             err = otp_write(USER_AREA_OFFSET(dm_zero_count),
934                             USER_AREA_SIZE(dm_zero_count), sizeof(zero_bit_count),
935                             (uint8_t *)&zero_bit_count);
936             if (err != TFM_PLAT_ERR_SUCCESS) {
937                 return err;
938             }
939             break;
940         case LCM_LCS_RMA:
941             break;
942         case LCM_LCS_CM:
943         case LCM_LCS_INVALID:
944             return TFM_PLAT_ERR_SYSTEM_ERR;
945     }
946 
947     lcm_err = lcm_set_lcs(&LCM_DEV_S, new_lcs, gppc_val);
948     if (lcm_err != LCM_ERROR_NONE) {
949         return TFM_PLAT_ERR_SYSTEM_ERR;
950     }
951 
952     return TFM_PLAT_ERR_SUCCESS;
953 }
954 
tfm_plat_otp_write(enum tfm_otp_element_id_t id,size_t in_len,const uint8_t * in)955 enum tfm_plat_err_t tfm_plat_otp_write(enum tfm_otp_element_id_t id,
956                                        size_t in_len, const uint8_t *in)
957 {
958 #ifdef RSE_HAS_MANUFACTURING_DATA
959     enum tfm_plat_err_t err;
960     size_t manufacturing_data_size = 0;
961 #endif
962     uint32_t bl1_2_offset;
963 
964     if (id >= PLAT_OTP_ID_MAX) {
965         return TFM_PLAT_ERR_INVALID_INPUT;
966     }
967 
968     if (id >= PLAT_OTP_ID_BL2_ROTPK_MAX && id <= PLAT_OTP_ID_BL2_ROTPK_8) {
969         return TFM_PLAT_ERR_UNSUPPORTED;
970     }
971     if (id >= PLAT_OTP_ID_NV_COUNTER_BL2_MAX && id <= PLAT_OTP_ID_NV_COUNTER_BL2_8) {
972         return TFM_PLAT_ERR_UNSUPPORTED;
973     }
974 
975     switch (id) {
976     case PLAT_OTP_ID_LCS:
977         return otp_write_lcs(in_len, in);
978     case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
979     case PLAT_OTP_ID_KEY_SECURE_ENCRYPTION:
980     case PLAT_OTP_ID_KEY_NON_SECURE_ENCRYPTION:
981         return otp_write_encrypted(otp_offsets[id], otp_sizes[id], in_len, in,
982                                    OTP_ROM_ENCRYPTION_KEY);
983     case PLAT_OTP_ID_BL1_2_IMAGE:
984 #ifdef RSE_HAS_MANUFACTURING_DATA
985         err = otp_read(USER_AREA_OFFSET(manufacturing_data.header.size),
986                        USER_AREA_SIZE(manufacturing_data.header.size),
987                        sizeof(manufacturing_data_size), (uint8_t *)&manufacturing_data_size);
988         if (err != TFM_PLAT_ERR_SUCCESS) {
989             return err;
990         }
991 
992         bl1_2_offset = USER_AREA_OFFSET(manufacturing_data.header) - manufacturing_data_size - in_len;
993 #else
994         bl1_2_offset = USER_AREA_OFFSET(dma_initial_command_sequence) - in_len;
995 #endif
996 
997         return otp_write(bl1_2_offset, otp_sizes[id], in_len, in);
998     default:
999         return otp_write(otp_offsets[id], otp_sizes[id], in_len, in);
1000     }
1001 }
1002 
1003 
tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,size_t * size)1004 enum tfm_plat_err_t tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,
1005                                           size_t *size)
1006 {
1007     if (id >= PLAT_OTP_ID_MAX) {
1008         return TFM_PLAT_ERR_INVALID_INPUT;
1009     }
1010 
1011     if (id >= PLAT_OTP_ID_BL2_ROTPK_MAX && id <= PLAT_OTP_ID_BL2_ROTPK_8) {
1012         return TFM_PLAT_ERR_UNSUPPORTED;
1013     }
1014     if (id >= PLAT_OTP_ID_NV_COUNTER_BL2_MAX && id <= PLAT_OTP_ID_NV_COUNTER_BL2_8) {
1015         return TFM_PLAT_ERR_UNSUPPORTED;
1016     }
1017 
1018     *size = otp_sizes[id];
1019 
1020     return TFM_PLAT_ERR_SUCCESS;
1021 }
1022 
tfm_plat_otp_secure_provisioning_start(void)1023 enum tfm_plat_err_t tfm_plat_otp_secure_provisioning_start(void)
1024 {
1025     enum lcm_bool_t sp_enabled;
1026     enum lcm_error_t lcm_err;
1027 #if LCM_VERSION == 0
1028     static uint8_t __ALIGNED(INTEGRITY_CHECKER_REQUIRED_ALIGNMENT) dummy_key_value[32] = {
1029                                                        0x01, 0x02, 0x03, 0x04,
1030                                                        0x01, 0x02, 0x03, 0x04,
1031                                                        0x01, 0x02, 0x03, 0x04,
1032                                                        0x01, 0x02, 0x03, 0x04,
1033                                                        0x01, 0x02, 0x03, 0x04,
1034                                                        0x01, 0x02, 0x03, 0x04,
1035                                                        0x01, 0x02, 0x03, 0x04,
1036                                                        0x01, 0x02, 0x03, 0x04};
1037     uint32_t gppc_val = 0x0800;
1038     uint32_t dm_config_2 = 0xFFFFFFFFu;
1039     enum lcm_lcs_t lcs;
1040 #endif /* LCM_VERSION == 0 */
1041 
1042     lcm_err = lcm_get_sp_enabled(&LCM_DEV_S, &sp_enabled);
1043     if (lcm_err != LCM_ERROR_NONE) {
1044         return TFM_PLAT_ERR_SYSTEM_ERR;
1045     }
1046 
1047     if (sp_enabled != LCM_TRUE) {
1048         lcm_set_sp_enabled(&LCM_DEV_S);
1049     } else {
1050 #if LCM_VERSION == 0
1051         /* Now we're in SP mode, if we have the R0 LCM, we should make sure the
1052          * transition will occur.
1053          */
1054         lcm_err = lcm_get_lcs(&LCM_DEV_S, &lcs);
1055         if (lcm_err != LCM_ERROR_NONE) {
1056             return TFM_PLAT_ERR_SYSTEM_ERR;
1057         }
1058 
1059         switch(lcs) {
1060         case LCM_LCS_CM:
1061             /* Trigger CM->DM by setting the uppermost bit of GPPC */
1062             lcm_err = lcm_otp_write(&LCM_DEV_S, OTP_OFFSET(cm_config_2), sizeof(gppc_val),
1063                                     (uint8_t *)&gppc_val);
1064             if (lcm_err != LCM_ERROR_NONE) {
1065                 return TFM_PLAT_ERR_SYSTEM_ERR;
1066             }
1067             break;
1068         case LCM_LCS_DM:
1069             /* Triggering DM->SE is trickier. Both KP_DM and KCE_DM must be set
1070              * with dummy data.
1071              */
1072             lcm_err = lcm_otp_write(&LCM_DEV_S, OTP_OFFSET(kp_dm),
1073                                     sizeof(dummy_key_value), dummy_key_value);
1074             if (lcm_err != LCM_ERROR_NONE) {
1075                 return TFM_PLAT_ERR_SYSTEM_ERR;
1076             }
1077 
1078             lcm_err = lcm_otp_write(&LCM_DEV_S, OTP_OFFSET(kce_dm),
1079                                     sizeof(dummy_key_value), dummy_key_value);
1080             if (lcm_err != LCM_ERROR_NONE) {
1081                 return TFM_PLAT_ERR_SYSTEM_ERR;
1082             }
1083 
1084             /* Finally, write dm_config to trigger the zero-count checking. It
1085              * doesn't matter what is written on the R0 LCM.
1086              */
1087             lcm_err = lcm_otp_write(&LCM_DEV_S, OTP_OFFSET(dm_config),
1088                                     sizeof(dm_config_2), (uint8_t *)&dm_config_2);
1089             if (lcm_err != LCM_ERROR_NONE && lcm_err != LCM_ERROR_WRITE_VERIFY_FAIL) {
1090                 return TFM_PLAT_ERR_SYSTEM_ERR;
1091             }
1092             break;
1093         default:
1094             break;
1095         }
1096 
1097 #endif /* LCM_VERSION == 0 */
1098     }
1099 
1100     return TFM_PLAT_ERR_SUCCESS;
1101 }
1102 
tfm_plat_otp_secure_provisioning_finish(void)1103 enum tfm_plat_err_t tfm_plat_otp_secure_provisioning_finish(void)
1104 {
1105     tfm_hal_system_reset();
1106 
1107     /* We'll never get here */
1108     return TFM_PLAT_ERR_SUCCESS;
1109 }
1110