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)&REGION_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