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