1 /*
2 * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <string.h>
9 #include "target_cfg.h"
10 #include "region.h"
11 #include "tfm_hal_device_header.h"
12 #include "boot_hal.h"
13 #include "Driver_Flash.h"
14 #include "flash_layout.h"
15 #ifdef CRYPTO_HW_ACCELERATOR
16 #include "crypto_hw.h"
17 #include "fih.h"
18 #endif /* CRYPTO_HW_ACCELERATOR */
19
20 #ifdef TFM_MEASURED_BOOT_API
21 #include "region_defs.h"
22 #include "tfm_boot_status.h"
23 #include "boot_measurement.h"
24 #endif /* TFM_MEASURED_BOOT_API */
25
26 /* Flash device names must be specified by target */
27 #ifdef FLASH_DEV_NAME
28 extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
29 #endif /* FLASH_DEV_NAME */
30 #ifdef FLASH_DEV_NAME_2
31 extern ARM_DRIVER_FLASH FLASH_DEV_NAME_2;
32 #endif /* FLASH_DEV_NAME_2 */
33 #ifdef FLASH_DEV_NAME_3
34 extern ARM_DRIVER_FLASH FLASH_DEV_NAME_3;
35 #endif /* FLASH_DEV_NAME_3 */
36 #ifdef FLASH_DEV_NAME_SCRATCH
37 extern ARM_DRIVER_FLASH FLASH_DEV_NAME_SCRATCH;
38 #endif /* FLASH_DEV_NAME_SCRATCH */
39
40 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
41 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
42 #if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) \
43 || defined(__ARM_ARCH_8_1M_MAIN__)
44 REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
45 #endif /* defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) \
46 || defined(__ARM_ARCH_8_1M_MAIN__) */
47 #if defined(__ICCARM__)
48 #pragma required = ER_DATA$$Base
49 #pragma required = ARM_LIB_HEAP$$Limit
50 #endif
51
boot_clear_ram_area(void)52 __WEAK __attribute__((naked)) void boot_clear_ram_area(void)
53 {
54 __ASM volatile(
55 #if !defined(__ICCARM__)
56 ".syntax unified \n"
57 #endif
58 "movs r0, #0 \n"
59 #if !defined(__ICCARM__)
60 "ldr r1, =Image$$ER_DATA$$Base \n"
61 "ldr r2, =Image$$ARM_LIB_HEAP$$ZI$$Limit \n"
62 #else
63 "ldr r1, =ER_DATA$$Base \n"
64 "ldr r2, =ARM_LIB_HEAP$$Limit \n"
65 #endif
66 "subs r2, r2, r1 \n"
67 "Loop: \n"
68 "subs r2, #4 \n"
69 "blt Clear_done \n"
70 "str r0, [r1, r2] \n"
71 "b Loop \n"
72 "Clear_done: \n"
73 "bx lr \n"
74 : : : "r0" , "r1" , "r2" , "memory"
75 );
76 }
77
78 /*!
79 * \brief Chain-loading the next image in the boot sequence.
80 *
81 * This function calls the Reset_Handler of the next image in the boot sequence,
82 * usually it is the secure firmware. Before passing the execution to next image
83 * there is conditional rule to remove the secrets from the memory. This must be
84 * done if the following conditions are satisfied:
85 * - Memory is shared between SW components at different stages of the trusted
86 * boot process.
87 * - There are secrets in the memory: KDF parameter, symmetric key,
88 * manufacturer sensitive code/data, etc.
89 */
90 #if defined(__ICCARM__)
91 #pragma required = boot_clear_ram_area
92 #endif
93
boot_jump_to_next_image(uint32_t reset_handler_addr)94 __WEAK __attribute__((naked)) void boot_jump_to_next_image(uint32_t reset_handler_addr)
95 {
96 __ASM volatile(
97 #if !defined(__ICCARM__)
98 ".syntax unified \n"
99 #endif
100 "mov r7, r0 \n"
101 "bl boot_clear_ram_area \n" /* Clear RAM before jump */
102 "movs r0, #0 \n" /* Clear registers: R0-R12, */
103 "mov r1, r0 \n" /* except R7 */
104 "mov r2, r0 \n"
105 "mov r3, r0 \n"
106 "mov r4, r0 \n"
107 "mov r5, r0 \n"
108 "mov r6, r0 \n"
109 "mov r8, r0 \n"
110 "mov r9, r0 \n"
111 "mov r10, r0 \n"
112 "mov r11, r0 \n"
113 "mov r12, r0 \n"
114 "mov lr, r0 \n"
115 "bx r7 \n" /* Jump to Reset_handler */
116 );
117 }
118
119 /* bootloader platform-specific hw initialization */
boot_platform_init(void)120 __WEAK int32_t boot_platform_init(void)
121 {
122 int32_t result;
123
124 #if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) \
125 || defined(__ARM_ARCH_8_1M_MAIN__)
126 /* Initialize stack limit register */
127 uint32_t msp_stack_bottom =
128 (uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
129
130 __set_MSPLIM(msp_stack_bottom);
131 #endif /* defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) \
132 || defined(__ARM_ARCH_8_1M_MAIN__) */
133
134 #ifdef FLASH_DEV_NAME
135 result = FLASH_DEV_NAME.Initialize(NULL);
136 if (result != ARM_DRIVER_OK) {
137 return 1;
138 }
139 #endif /* FLASH_DEV_NAME */
140 #ifdef FLASH_DEV_NAME_2
141 result = FLASH_DEV_NAME_2.Initialize(NULL);
142 if (result != ARM_DRIVER_OK) {
143 return 1;
144 }
145 #endif /* FLASH_DEV_NAME_2 */
146 #ifdef FLASH_DEV_NAME_3
147 result = FLASH_DEV_NAME_3.Initialize(NULL);
148 if (result != ARM_DRIVER_OK) {
149 return 1;
150 }
151 #endif /* FLASH_DEV_NAME_3 */
152 #ifdef FLASH_DEV_NAME_SCRATCH
153 result = FLASH_DEV_NAME_SCRATCH.Initialize(NULL);
154 if (result != ARM_DRIVER_OK) {
155 return 1;
156 }
157 #endif /* FLASH_DEV_NAME_SCRATCH */
158
159 return 0;
160 }
161
boot_platform_post_init(void)162 __WEAK int32_t boot_platform_post_init(void)
163 {
164 #ifdef CRYPTO_HW_ACCELERATOR
165 int32_t result;
166
167 result = crypto_hw_accelerator_init();
168 if (result) {
169 return 1;
170 }
171
172 (void)fih_delay_init();
173 #endif /* CRYPTO_HW_ACCELERATOR */
174
175 return 0;
176 }
177
boot_platform_quit(struct boot_arm_vector_table * vt)178 __WEAK void boot_platform_quit(struct boot_arm_vector_table *vt)
179 {
180 /* Clang at O0, stores variables on the stack with SP relative addressing.
181 * When manually set the SP then the place of reset vector is lost.
182 * Static variables are stored in 'data' or 'bss' section, change of SP has
183 * no effect on them.
184 */
185 static struct boot_arm_vector_table *vt_cpy;
186 int32_t result;
187
188 #ifdef CRYPTO_HW_ACCELERATOR
189 result = crypto_hw_accelerator_finish();
190 if (result) {
191 while (1){}
192 }
193 #endif /* CRYPTO_HW_ACCELERATOR */
194
195 #ifdef FLASH_DEV_NAME
196 result = FLASH_DEV_NAME.Uninitialize();
197 if (result != ARM_DRIVER_OK) {
198 while(1) {}
199 }
200 #endif /* FLASH_DEV_NAME */
201 #ifdef FLASH_DEV_NAME_2
202 result = FLASH_DEV_NAME_2.Uninitialize();
203 if (result != ARM_DRIVER_OK) {
204 while(1) {}
205 }
206 #endif /* FLASH_DEV_NAME_2 */
207 #ifdef FLASH_DEV_NAME_3
208 result = FLASH_DEV_NAME_3.Uninitialize();
209 if (result != ARM_DRIVER_OK) {
210 while(1) {}
211 }
212 #endif /* FLASH_DEV_NAME_3 */
213 #ifdef FLASH_DEV_NAME_SCRATCH
214 result = FLASH_DEV_NAME_SCRATCH.Uninitialize();
215 if (result != ARM_DRIVER_OK) {
216 while(1) {}
217 }
218 #endif /* FLASH_DEV_NAME_SCRATCH */
219
220 vt_cpy = vt;
221 #if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) \
222 || defined(__ARM_ARCH_8_1M_MAIN__)
223 /* Restore the Main Stack Pointer Limit register's reset value
224 * before passing execution to runtime firmware to make the
225 * bootloader transparent to it.
226 */
227 __set_MSPLIM(0);
228 #endif /* defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) \
229 || defined(__ARM_ARCH_8_1M_MAIN__) */
230
231 __set_MSP(vt_cpy->msp);
232 __DSB();
233 __ISB();
234
235 boot_jump_to_next_image(vt_cpy->reset);
236 }
237
boot_platform_pre_load(uint32_t image_id)238 __WEAK int boot_platform_pre_load(uint32_t image_id)
239 {
240 return 0;
241 }
242
boot_platform_post_load(uint32_t image_id)243 __WEAK int boot_platform_post_load(uint32_t image_id)
244 {
245 return 0;
246 }
247
boot_platform_should_load_image(uint32_t image_id)248 __WEAK bool boot_platform_should_load_image(uint32_t image_id)
249 {
250 return true;
251 }
252
253 #ifdef TFM_MEASURED_BOOT_API
boot_add_data_to_shared_area(uint8_t major_type,uint16_t minor_type,size_t size,const uint8_t * data)254 static int boot_add_data_to_shared_area(uint8_t major_type,
255 uint16_t minor_type,
256 size_t size,
257 const uint8_t *data)
258 {
259 struct shared_data_tlv_entry tlv_entry = {0};
260 struct tfm_boot_data *boot_data;
261 uintptr_t tlv_end, offset;
262
263 if (data == NULL) {
264 return -1;
265 }
266
267 boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
268
269 /* Check whether the shared area needs to be initialized. */
270 if ((boot_data->header.tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) ||
271 (boot_data->header.tlv_tot_len > BOOT_TFM_SHARED_DATA_SIZE)) {
272
273 memset((void *)BOOT_TFM_SHARED_DATA_BASE, 0, BOOT_TFM_SHARED_DATA_SIZE);
274 boot_data->header.tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
275 boot_data->header.tlv_tot_len = SHARED_DATA_HEADER_SIZE;
276 }
277
278 /* Get the boundaries of TLV section. */
279 tlv_end = BOOT_TFM_SHARED_DATA_BASE + boot_data->header.tlv_tot_len;
280 offset = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE;
281
282 /* Check whether TLV entry is already added. Iterates over the TLV section
283 * looks for the same entry if found then returns with error.
284 */
285 while (offset < tlv_end) {
286 /* Create local copy to avoid unaligned access */
287 memcpy(&tlv_entry, (const void *)offset, SHARED_DATA_ENTRY_HEADER_SIZE);
288 if (GET_MAJOR(tlv_entry.tlv_type) == major_type &&
289 GET_MINOR(tlv_entry.tlv_type) == minor_type) {
290 return -1;
291 }
292
293 offset += SHARED_DATA_ENTRY_SIZE(tlv_entry.tlv_len);
294 }
295
296 /* Add TLV entry. */
297 tlv_entry.tlv_type = SET_TLV_TYPE(major_type, minor_type);
298 tlv_entry.tlv_len = size;
299
300 /* Check integer overflow and overflow of shared data area. */
301 if (SHARED_DATA_ENTRY_SIZE(size) >
302 (UINT16_MAX - boot_data->header.tlv_tot_len)) {
303 return -1;
304 } else if ((SHARED_DATA_ENTRY_SIZE(size) + boot_data->header.tlv_tot_len) >
305 BOOT_TFM_SHARED_DATA_SIZE) {
306 return -1;
307 }
308
309 offset = tlv_end;
310 memcpy((void *)offset, &tlv_entry, SHARED_DATA_ENTRY_HEADER_SIZE);
311
312 offset += SHARED_DATA_ENTRY_HEADER_SIZE;
313 memcpy((void *)offset, data, size);
314
315 boot_data->header.tlv_tot_len += SHARED_DATA_ENTRY_SIZE(size);
316
317 return 0;
318 }
319
boot_store_measurement(uint8_t index,const uint8_t * measurement,size_t measurement_size,const struct boot_measurement_metadata * metadata,bool lock_measurement)320 __WEAK int boot_store_measurement(
321 uint8_t index,
322 const uint8_t *measurement,
323 size_t measurement_size,
324 const struct boot_measurement_metadata *metadata,
325 bool lock_measurement)
326 {
327 uint16_t minor_type;
328 uint8_t claim;
329 int rc;
330
331 if (index >= BOOT_MEASUREMENT_SLOT_MAX) {
332 return -1;
333 }
334
335 minor_type = SET_MBS_MINOR(index, SW_MEASURE_METADATA);
336 rc = boot_add_data_to_shared_area(TLV_MAJOR_MBS,
337 minor_type,
338 sizeof(struct boot_measurement_metadata),
339 (const uint8_t *)metadata);
340 if (rc) {
341 return rc;
342 }
343
344 claim = lock_measurement ? SW_MEASURE_VALUE_NON_EXTENDABLE
345 : SW_MEASURE_VALUE;
346 minor_type = SET_MBS_MINOR(index, claim);
347 rc = boot_add_data_to_shared_area(TLV_MAJOR_MBS,
348 minor_type,
349 measurement_size,
350 measurement);
351
352 return rc;
353 }
354 #endif /* TFM_MEASURED_BOOT_API */
355
boot_initiate_recovery_mode(uint32_t image_id)356 __WEAK int boot_initiate_recovery_mode(uint32_t image_id)
357 {
358 (void)image_id;
359
360 /* We haven't done anything, therefore recovery has failed */
361 return 1;
362 }
363