1 /*
2  * Copyright (c) 2021-2024, 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 "tfm_plat_provisioning.h"
11 #include "tfm_plat_otp.h"
12 #include "boot_hal.h"
13 #ifdef TFM_MEASURED_BOOT_API
14 #include "boot_measurement.h"
15 #endif /* TFM_MEASURED_BOOT_API */
16 #include "psa/crypto.h"
17 #include "region_defs.h"
18 #include "log.h"
19 #include "util.h"
20 #include "image.h"
21 #include "fih.h"
22 
23 /* Disable both semihosting code and argv usage for main */
24 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
25 __asm("  .global __ARM_use_no_argv\n");
26 #endif
27 
28 uint8_t computed_bl1_2_hash[BL1_2_HASH_SIZE];
29 
30 #ifdef TFM_MEASURED_BOOT_API
31 #if (BL1_2_HASH_SIZE == 32)
32 #define BL1_2_HASH_ALG  PSA_ALG_SHA_256
33 #elif (BL1_2_HASH_SIZE == 64)
34 #define BL1_2_HASH_ALG  PSA_ALG_SHA_512
35 #else
36 #error "The specified BL1_2_HASH_SIZE is not supported with measured boot."
37 #endif /* BL1_2_HASH_SIZE */
38 
collect_boot_measurement(void)39 static void collect_boot_measurement(void)
40 {
41     struct boot_measurement_metadata bl1_2_metadata = {
42         .measurement_type = BL1_2_HASH_ALG,
43         .signer_id = { 0 },
44         .signer_id_size = BL1_2_HASH_SIZE,
45         .sw_type = "BL1_2",
46         .sw_version = { 0 },
47     };
48 
49     /* Missing metadata:
50      * - image version: not available,
51      * - signer ID: the BL1_2 image is not signed.
52      */
53     if (boot_store_measurement(BOOT_MEASUREMENT_SLOT_BL1_2, computed_bl1_2_hash,
54                                BL1_2_HASH_SIZE, &bl1_2_metadata, true)) {
55         BL1_LOG("[WRN] Failed to store boot measurement of BL1_2\r\n");
56     }
57 }
58 #endif /* TFM_MEASURED_BOOT_API */
59 
validate_image_at_addr(const uint8_t * image)60 fih_int validate_image_at_addr(const uint8_t *image)
61 {
62     enum tfm_plat_err_t plat_err;
63     uint8_t stored_bl1_2_hash[BL1_2_HASH_SIZE];
64     fih_int fih_rc = FIH_FAILURE;
65 
66     FIH_CALL(bl1_sha256_compute, fih_rc, image, BL1_2_CODE_SIZE,
67                                          computed_bl1_2_hash);
68     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
69         FIH_RET(FIH_FAILURE);
70     }
71 
72     plat_err = tfm_plat_otp_read(PLAT_OTP_ID_BL1_2_IMAGE_HASH, BL1_2_HASH_SIZE,
73                                  stored_bl1_2_hash);
74     fih_rc = fih_int_encode_zero_equality(plat_err);
75     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
76         FIH_RET(FIH_FAILURE);
77     }
78 
79     FIH_CALL(bl_fih_memeql, fih_rc, computed_bl1_2_hash,
80                                     stored_bl1_2_hash, BL1_2_HASH_SIZE);
81     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
82         FIH_RET(FIH_FAILURE);
83     }
84 
85     FIH_RET(FIH_SUCCESS);
86 }
87 
main(void)88 int main(void)
89 {
90     int rc;
91     fih_int fih_rc = FIH_FAILURE;
92     fih_int recovery_succeeded = FIH_FAILURE;
93 
94     fih_rc = fih_int_encode_zero_equality(boot_platform_init());
95     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
96         FIH_PANIC;
97     }
98     BL1_LOG("[INF] Starting TF-M BL1_1\r\n");
99 
100     if (tfm_plat_provisioning_is_required()) {
101         if (tfm_plat_provisioning_perform()) {
102             BL1_LOG("[ERR] BL1 provisioning failed\r\n");
103             FIH_PANIC;
104         }
105     }
106 
107     tfm_plat_provisioning_check_for_dummy_keys();
108 
109     fih_rc = fih_int_encode_zero_equality(boot_platform_post_init());
110     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
111         FIH_PANIC;
112     }
113 
114 #ifdef TEST_BL1_1
115     run_bl1_1_testsuite();
116 #endif /* TEST_BL1_1 */
117 
118     fih_rc = fih_int_encode_zero_equality(boot_platform_pre_load(0));
119     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
120         FIH_PANIC;
121     }
122 
123     do {
124         /* Copy BL1_2 from OTP into SRAM*/
125         FIH_CALL(bl1_read_bl1_2_image, fih_rc, (uint8_t *)BL1_2_CODE_START);
126         if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
127             FIH_PANIC;
128         }
129 
130         FIH_CALL(validate_image_at_addr, fih_rc, (uint8_t *)BL1_2_CODE_START);
131 
132         if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
133             BL1_LOG("[ERR] BL1_2 image failed to validate\r\n");
134 
135             recovery_succeeded = fih_int_encode_zero_equality(boot_initiate_recovery_mode(0));
136             if (fih_not_eq(recovery_succeeded, FIH_SUCCESS)) {
137                 FIH_PANIC;
138             }
139         }
140     } while (fih_not_eq(fih_rc, FIH_SUCCESS));
141 
142     fih_rc = fih_int_encode_zero_equality(boot_platform_post_load(0));
143     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
144         FIH_PANIC;
145     }
146 
147 #ifdef TFM_MEASURED_BOOT_API
148     collect_boot_measurement();
149 #endif /* TFM_MEASURED_BOOT_API */
150 
151     BL1_LOG("[INF] Jumping to BL1_2\r\n");
152     /* Jump to BL1_2 */
153     boot_platform_quit((struct boot_arm_vector_table *)BL1_2_CODE_START);
154 
155     /* This should never happen */
156     FIH_PANIC;
157 }
158