1 /*
2  * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "sic_boot.h"
9 
10 #include "device_definition.h"
11 #include "bl2_image_id.h"
12 #include "region_defs.h"
13 #include "tfm_plat_otp.h"
14 #include "plat_def_fip_uuid.h"
15 #include "rse_kmu_slot_ids.h"
16 #if RSE_USE_HOST_FLASH
17 #include "host_flash_atu.h"
18 #endif /* RSE_USE_HOST_FLASH */
19 
20 #include <string.h>
21 
22 #define RSE_ATU_S_IMAGE_XIP_REGION  0
23 #define RSE_ATU_NS_IMAGE_XIP_REGION 1
24 
25 #define RSE_SIC_S_IMAGE_DECRYPT_REGION  0
26 #define RSE_SIC_NS_IMAGE_DECRYPT_REGION 1
27 
28 #define FLASH_SIC_HTR_SIZE 0x800
29 #define SIC_BASE_ADDR_MASK 0xFF000000u
30 
31 uint32_t s_image_offset;
32 uint32_t ns_image_offset;
33 
34 struct rse_xip_htr_table {
35     uint32_t fw_revision;
36     uint32_t nonce[2];
37     size_t htr_size;
38     uint8_t htr[FLASH_SIC_HTR_SIZE];
39 };
40 
sic_boot_init(void)41 enum sic_boot_err_t sic_boot_init(void)
42 {
43     enum sic_error_t sic_err;
44 
45     /* The regions must be contiguous. This check is static, so will be compiled
46      * out if it succeeds.
47      */
48     if (RSE_RUNTIME_NS_XIP_BASE_S != RSE_RUNTIME_S_XIP_BASE_S + FLASH_S_PARTITION_SIZE) {
49         return SIC_BOOT_INVALID_REGION;
50     }
51 
52     sic_err = sic_auth_init(&SIC_DEV_S, SIC_DIGEST_SIZE_256,
53                             SIC_DIGEST_COMPARE_FIRST_QWORD,
54                             RSE_RUNTIME_S_XIP_BASE_S,
55                             FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE);
56     if (sic_err != SIC_ERROR_NONE) {
57         return SIC_BOOT_ERR_AUTH_INIT;
58     }
59 
60     sic_err = sic_decrypt_init(&SIC_DEV_S, SIC_DECRYPT_KEYSIZE_256, false);
61     if (sic_err != SIC_ERROR_NONE) {
62         return SIC_BOOT_ERR_DECR_INIT;
63     }
64 
65     return SIC_BOOT_SUCCESS;
66 }
67 
68 enum sic_boot_err_t
sic_boot_setup_auth_and_decrypt(uintptr_t sictbl,uintptr_t img_addr,size_t img_size,uint8_t region_idx,enum rse_kmu_slot_id_t key)69 sic_boot_setup_auth_and_decrypt(uintptr_t sictbl,
70                                 uintptr_t img_addr,
71                                 size_t img_size,
72                                 uint8_t region_idx,
73                                 enum rse_kmu_slot_id_t key)
74 
75 {
76     enum sic_error_t sic_err;
77     enum kmu_error_t kmu_err;
78     size_t table_offset;
79     uintptr_t base_addr = (img_addr & SIC_BASE_ADDR_MASK);
80     struct rse_xip_htr_table *xip_table = (struct rse_xip_htr_table *)sictbl;
81     size_t page_size = sic_page_size_get(&SIC_DEV_S);
82 
83     /* The first code page must be address aligned to the page size */
84     if ((img_addr % page_size) != 0u) {
85         return SIC_BOOT_INVALID_ALIGNMENT;
86     }
87 
88     /* The image must be in SIC address space */
89     if ((base_addr != SIC_HOST_BASE_NS) && (base_addr != SIC_HOST_BASE_S)) {
90         return SIC_BOOT_INVALID_REGION;
91     }
92 
93     /* The image must be mapped to the SIC region */
94     if ((img_addr < base_addr) ||
95         ((img_addr + img_size) > (base_addr + SIC_MAPPABLE_SIZE))) {
96         return SIC_BOOT_INVALID_REGION; /* Image not in SIC region */
97     }
98 
99     /* Calculate offset in HTR where the SICTBL is copied */
100     table_offset = ((img_addr - base_addr) / page_size); /* in pages */
101     table_offset *= 32u; /* digest for each page is 32bytes (256bits) */
102 
103     /* Secure I-cache HTR setup */
104     sic_err = sic_auth_table_set(&SIC_DEV_S, (uint32_t *)xip_table->htr,
105                                  xip_table->htr_size, table_offset);
106     if (sic_err != SIC_ERROR_NONE) {
107         return SIC_BOOT_ERR_AUTH_SETUP;
108     }
109 
110     /* Secure I-cache DR setup */
111     sic_err = sic_decrypt_region_enable(&SIC_DEV_S, region_idx,
112                                         img_addr, img_size,
113                                         xip_table->fw_revision,
114                                         xip_table->nonce, NULL);
115     if (sic_err != SIC_ERROR_NONE) {
116         return SIC_BOOT_ERR_DECR_SETUP;
117     }
118 
119     kmu_err = kmu_export_key(&KMU_DEV_S, key);
120     if (kmu_err != KMU_ERROR_NONE) {
121         return SIC_BOOT_ERR_DECRKEY_EX;
122     }
123 
124     return SIC_BOOT_SUCCESS;
125 }
126 
sic_boot_enable_auth_and_decrypt(void)127 enum sic_boot_err_t sic_boot_enable_auth_and_decrypt(void)
128 {
129     enum sic_error_t sic_err;
130 
131     sic_err = sic_auth_enable(&SIC_DEV_S);
132     if (sic_err != SIC_ERROR_NONE) {
133         return SIC_BOOT_ERR_ENABLE;
134     }
135 
136     sic_err = sic_enable(&SIC_DEV_S);
137     if (sic_err != SIC_ERROR_NONE) {
138         return SIC_BOOT_ERR_ENABLE;
139     }
140 
141     return SIC_BOOT_SUCCESS;
142 }
143 
144 #ifdef RSE_USE_HOST_FLASH
sic_boot_post_load(uint32_t image_id,uint32_t image_load_offset)145 enum sic_boot_err_t sic_boot_post_load(uint32_t image_id, uint32_t image_load_offset)
146 {
147     enum rse_kmu_slot_id_t decrypt_key_slot;
148     uint32_t table;
149     uint32_t decrypt_region;
150     uint32_t xip_region_base_addr;
151     size_t xip_region_size;
152     size_t max_region_size;
153     uint64_t fip_offsets[2];
154     bool fip_found[2];
155     uint64_t fip_offset;
156     uint32_t atu_region;
157     uuid_t image_uuid;
158     uint32_t *image_offset;
159 
160     int rc;
161 
162     rc = host_flash_atu_get_fip_offsets(fip_found, fip_offsets);
163     if (rc) {
164         return SIC_BOOT_INVALID_REGION;
165     }
166 
167     switch (image_id) {
168     case RSE_BL2_IMAGE_NS:
169         table = BL2_XIP_TABLES_START + FLASH_SIC_TABLE_SIZE + BL2_HEADER_SIZE;
170 
171         if (image_load_offset >= FLASH_AREA_11_OFFSET
172             && image_load_offset < FLASH_AREA_11_OFFSET + FLASH_AREA_11_SIZE) {
173             if (fip_found[0]) {
174                 fip_offset = fip_offsets[0];
175             } else {
176                 return SIC_BOOT_INVALID_REGION;
177             }
178         } else if (image_load_offset >= FLASH_AREA_13_OFFSET
179                    && image_load_offset < FLASH_AREA_13_OFFSET + FLASH_AREA_13_SIZE) {
180             if (fip_found[1]) {
181                 fip_offset = fip_offsets[1];
182             } else {
183                 return SIC_BOOT_INVALID_REGION;
184             }
185         } else {
186             return SIC_BOOT_INVALID_REGION;
187         }
188 
189         decrypt_key_slot = RSE_KMU_SLOT_NON_SECURE_ENCRYPTION_KEY;
190         atu_region = RSE_ATU_NS_IMAGE_XIP_REGION;
191         decrypt_region = RSE_SIC_NS_IMAGE_DECRYPT_REGION;
192         xip_region_base_addr = RSE_RUNTIME_NS_XIP_BASE_NS;
193         max_region_size = NS_CODE_SIZE;
194         image_uuid = UUID_RSE_FIRMWARE_NS;
195         image_offset = &ns_image_offset;
196 
197         break;
198     case RSE_BL2_IMAGE_S:
199         table = BL2_XIP_TABLES_START + BL2_HEADER_SIZE;
200 
201         if (image_load_offset >= FLASH_AREA_10_OFFSET
202             && image_load_offset < FLASH_AREA_10_OFFSET + FLASH_AREA_10_SIZE) {
203             fip_offset = fip_offsets[0];
204         } else if (image_load_offset >= FLASH_AREA_12_OFFSET
205             && image_load_offset < FLASH_AREA_12_OFFSET + FLASH_AREA_12_SIZE) {
206             fip_offset = fip_offsets[1];
207         } else {
208             return SIC_BOOT_INVALID_REGION;
209         }
210 
211         decrypt_key_slot = RSE_KMU_SLOT_SECURE_ENCRYPTION_KEY;
212         atu_region = RSE_ATU_S_IMAGE_XIP_REGION;
213         decrypt_region = RSE_SIC_S_IMAGE_DECRYPT_REGION;
214         xip_region_base_addr = RSE_RUNTIME_S_XIP_BASE_S;
215         max_region_size = S_CODE_SIZE;
216         image_uuid = UUID_RSE_FIRMWARE_S;
217         image_offset = &s_image_offset;
218 
219         break;
220 
221     case RSE_BL2_IMAGE_AP:
222     case RSE_BL2_IMAGE_SCP:
223         return SIC_BOOT_SUCCESS;
224     default:
225         return SIC_BOOT_INVALID_REGION;
226     }
227 
228     rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offset,
229                                                          atu_region,
230                                                          xip_region_base_addr,
231                                                          image_uuid,
232                                                          image_offset,
233                                                          &xip_region_size);
234     if (rc) {
235         return SIC_BOOT_INVALID_REGION;
236     }
237 
238     /* RSE XIP images must be aligned to, at minimum, the SIC authentication
239      * page size and the SIC decrypt page size. Alignments that do not match
240      * the ATU page size cause problems in jumping to NS code, and seem to
241      * cause startup failure in some cases, so 8KiB alignment is required.
242      */
243     if (*image_offset % 0x1000 != 0) {
244         return SIC_BOOT_INVALID_ALIGNMENT;
245     }
246 
247     if (xip_region_size > max_region_size) {
248         return SIC_BOOT_INVALID_REGION;
249     }
250 
251 
252     return sic_boot_setup_auth_and_decrypt(table,
253                                            xip_region_base_addr,
254                                            xip_region_size,
255                                            decrypt_region,
256                                            decrypt_key_slot);
257 }
258 
sic_boot_pre_quit(struct boot_arm_vector_table ** vt_cpy)259 enum sic_boot_err_t sic_boot_pre_quit(struct boot_arm_vector_table **vt_cpy)
260 {
261     enum sic_boot_err_t sic_err;
262 
263     sic_err = sic_boot_enable_auth_and_decrypt();
264     if (sic_err != SIC_BOOT_SUCCESS) {
265         return sic_err;
266     }
267 
268     *vt_cpy = (struct boot_arm_vector_table *)(RSE_RUNTIME_S_XIP_BASE_S + s_image_offset);
269 
270     return SIC_BOOT_SUCCESS;
271 }
272 
273 #endif /* RSE_USE_HOST_FLASH */
274