1 /*
2 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "crypto.h"
9 #include "otp.h"
10 #include "boot_hal.h"
11 #include "uart_stdout.h"
12 #include "fih.h"
13 #include "util.h"
14 #include "log.h"
15 #include "image.h"
16 #include "region_defs.h"
17 #include "pq_crypto.h"
18
19 extern uint32_t platform_code_is_bl1_2;
20
21 #ifndef TFM_BL1_PQ_CRYPTO
image_hash_check(struct bl1_2_image_t * img)22 static fih_int image_hash_check(struct bl1_2_image_t *img)
23 {
24 uint8_t computed_bl2_hash[BL2_HASH_SIZE];
25 uint8_t stored_bl2_hash[BL2_HASH_SIZE];
26 fih_int fih_rc = FIH_FAILURE;
27
28 FIH_CALL(bl1_sha256_compute, fih_rc, (uint8_t *)&img->protected_values,
29 sizeof(img->protected_values),
30 computed_bl2_hash);
31 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
32 FIH_RET(fih_rc);
33 }
34
35 FIH_CALL(bl1_otp_read_bl2_image_hash, fih_rc, stored_bl2_hash);
36 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
37 FIH_RET(fih_rc);
38 }
39
40 FIH_CALL(bl_secure_memeql, fih_rc, computed_bl2_hash, stored_bl2_hash,
41 BL2_HASH_SIZE);
42 FIH_RET(fih_rc);
43 }
44 #endif /* !TFM_BL1_PQ_CRYPTO */
45
is_image_security_counter_valid(struct bl1_2_image_t * img)46 static fih_int is_image_security_counter_valid(struct bl1_2_image_t *img)
47 {
48 uint32_t security_counter;
49 fih_int fih_rc;
50
51 FIH_CALL(bl1_otp_read_nv_counter, fih_rc, BL1_NV_COUNTER_ID_BL2_IMAGE,
52 &security_counter);
53 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
54 FIH_RET(FIH_FAILURE);
55 }
56
57 /* Encodes 0 to true and 1 to false, so the actual comparison is flipped */
58 FIH_RET(
59 fih_int_encode_zero_equality(security_counter
60 > img->protected_values.security_counter));
61 }
62
is_image_signature_valid(struct bl1_2_image_t * img)63 static fih_int is_image_signature_valid(struct bl1_2_image_t *img)
64 {
65 fih_int fih_rc = FIH_FAILURE;
66
67 #ifdef TFM_BL1_PQ_CRYPTO
68 #warning PQ crypto is experimental, and should not be used in production
69 BL1_LOG("\033[1;31m[WRN] ");
70 BL1_LOG("PQ crypto is experimental, and should not be used in production");
71 BL1_LOG("\033[0m\r\n");
72 FIH_CALL(pq_crypto_verify, fih_rc, TFM_BL1_KEY_ROTPK_0,
73 (uint8_t *)&img->protected_values,
74 sizeof(img->protected_values),
75 img->header.sig,
76 sizeof(img->header.sig));
77 #else
78 FIH_CALL(image_hash_check, fih_rc, img);
79 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
80 FIH_RET(FIH_FAILURE);
81 }
82 #endif /* TFM_BL1_PQ_CRYPTO */
83
84 FIH_RET(fih_rc);
85 }
86
validate_image_at_addr(struct bl1_2_image_t * image)87 fih_int validate_image_at_addr(struct bl1_2_image_t *image)
88 {
89 fih_int fih_rc = FIH_FAILURE;
90
91 FIH_CALL(is_image_signature_valid, fih_rc, image);
92 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
93 BL1_LOG("[ERR] BL2 image signature failed to validate\r\n");
94 FIH_RET(FIH_FAILURE);
95 }
96 FIH_CALL(is_image_security_counter_valid, fih_rc, image);
97 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
98 BL1_LOG("[ERR] BL2 image security_counter failed to validate\r\n");
99 FIH_RET(FIH_FAILURE);
100 }
101
102 /* TODO work out if the image actually boots before updating the counter */
103 FIH_CALL(bl1_otp_write_nv_counter, fih_rc, BL1_NV_COUNTER_ID_BL2_IMAGE,
104 image->protected_values.security_counter);
105 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
106 BL1_LOG("[ERR] NV counter update failed\r\n");
107 FIH_RET(FIH_FAILURE);
108 }
109
110 FIH_RET(FIH_SUCCESS);
111 }
112
copy_and_decrypt_image(uint32_t image_id)113 fih_int copy_and_decrypt_image(uint32_t image_id)
114 {
115 int rc;
116 #ifdef TFM_BL1_MEMORY_MAPPED_FLASH
117 fih_int fih_rc;
118 #endif /* TFM_BL1_MEMORY_MAPPED_FLASH */
119 struct bl1_2_image_t *image_to_decrypt;
120 struct bl1_2_image_t *image_after_decrypt =
121 (struct bl1_2_image_t *)BL2_IMAGE_START;
122 uint8_t key_buf[32];
123 uint8_t label[] = "BL2_DECRYPTION_KEY";
124
125 #ifdef TFM_BL1_MEMORY_MAPPED_FLASH
126 /* If we have memory-mapped flash, we can do the decrypt directly from the
127 * flash and output to the SRAM. This is significantly faster if the AES
128 * invocation calls through to a crypto accelerator with a DMA, and slightly
129 * faster otherwise.
130 */
131 image_to_decrypt = (struct bl1_2_image_t *)(FLASH_BASE_ADDRESS +
132 bl1_image_get_flash_offset(image_id));
133
134 /* Copy everything that isn't encrypted, to prevent TOCTOU attacks and
135 * simplify logic.
136 */
137 FIH_CALL(bl_secure_memcpy, fih_rc, image_after_decrypt,
138 image_to_decrypt,
139 sizeof(struct bl1_2_image_t) -
140 sizeof(image_after_decrypt->protected_values.encrypted_data));
141 #else
142 /* If the flash isn't memory-mapped, defer to the flash driver to copy the
143 * entire block in to SRAM. We'll then do the decrypt in-place.
144 */
145 bl1_image_copy_to_sram(image_id, (uint8_t *)BL2_IMAGE_START);
146 image_to_decrypt = (struct bl1_2_image_t *)BL2_IMAGE_START;
147 #endif /* TFM_BL1_MEMORY_MAPPED_FLASH */
148
149 /* As the security counter is an attacker controlled parameter, bound the
150 * values to a sensible range. In this case, we choose 1024 as the bound as
151 * it is the same as the max amount of signatures as a H=10 LMS key.
152 */
153 if (image_to_decrypt->protected_values.security_counter >= 1024) {
154 FIH_RET(FIH_FAILURE);
155 }
156
157 /* The image security counter is used as a KDF input */
158 rc = bl1_derive_key(TFM_BL1_KEY_BL2_ENCRYPTION, label, sizeof(label),
159 (uint8_t *)&image_to_decrypt->protected_values.security_counter,
160 sizeof(image_to_decrypt->protected_values.security_counter),
161 key_buf, sizeof(key_buf));
162 if (rc) {
163 FIH_RET(fih_int_encode_zero_equality(rc));
164 }
165
166 rc = bl1_aes_256_ctr_decrypt(TFM_BL1_KEY_USER, key_buf,
167 image_after_decrypt->header.ctr_iv,
168 (uint8_t *)&image_to_decrypt->protected_values.encrypted_data,
169 sizeof(image_after_decrypt->protected_values.encrypted_data),
170 (uint8_t *)&image_after_decrypt->protected_values.encrypted_data);
171 if (rc) {
172 FIH_RET(fih_int_encode_zero_equality(rc));
173 }
174
175 if (image_after_decrypt->protected_values.encrypted_data.decrypt_magic
176 != BL1_2_IMAGE_DECRYPT_MAGIC_EXPECTED) {
177 FIH_RET(FIH_FAILURE);
178 }
179
180 FIH_RET(FIH_SUCCESS);
181 }
182
validate_image(uint32_t image_id)183 static fih_int validate_image(uint32_t image_id)
184 {
185 fih_int fih_rc = FIH_FAILURE;
186 struct bl1_2_image_t *image;
187
188 FIH_CALL(copy_and_decrypt_image, fih_rc, image_id);
189 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
190 BL1_LOG("[ERR] BL2 image failed to decrypt\r\n");
191 FIH_RET(FIH_FAILURE);
192 }
193 image = (struct bl1_2_image_t *)BL2_IMAGE_START;
194
195 BL1_LOG("[INF] BL2 image decrypted successfully\r\n");
196
197 FIH_CALL(validate_image_at_addr, fih_rc, image);
198 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
199 BL1_LOG("[ERR] BL2 image failed to validate\r\n");
200 FIH_RET(FIH_FAILURE);
201 }
202
203 BL1_LOG("[INF] BL2 image validated successfully\r\n");
204
205 FIH_RET(FIH_SUCCESS);
206 }
207
main(void)208 int main(void)
209 {
210 platform_code_is_bl1_2 = 1;
211 fih_int fih_rc = FIH_FAILURE;
212
213 fih_rc = fih_int_encode_zero_equality(boot_platform_init());
214 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
215 FIH_PANIC;
216 }
217 BL1_LOG("[INF] starting TF-M bl1_2\r\n");
218
219 fih_rc = fih_int_encode_zero_equality(boot_platform_post_init());
220 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
221 FIH_PANIC;
222 }
223
224 #ifdef TEST_BL1_2
225 run_bl1_2_testsuite();
226 #endif /* TEST_BL1_2 */
227
228 BL1_LOG("[INF] Attempting to boot image 0\r\n");
229 FIH_CALL(validate_image, fih_rc, 0);
230 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
231 BL1_LOG("[INF] Attempting to boot image 1\r\n");
232 FIH_CALL(validate_image, fih_rc, 1);
233 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
234 FIH_PANIC;
235 }
236 }
237
238 BL1_LOG("[INF] Jumping to BL2\r\n");
239 boot_platform_quit((struct boot_arm_vector_table *)BL2_CODE_START);
240
241 FIH_PANIC;
242 }
243