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