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 *)®ion_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 ®ion_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 *)®ion_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 ®ion_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