1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <strings.h>
8 #include "sdkconfig.h"
9 #include "esp_log.h"
10 #include "esp_efuse.h"
11 #include "esp_efuse_table.h"
12 #include "esp_secure_boot.h"
13 
14 #ifndef BOOTLOADER_BUILD
15 static __attribute__((unused)) const char *TAG = "secure_boot";
16 
17 #ifdef CONFIG_SECURE_BOOT
efuse_batch_write_begin(bool * need_fix)18 static void efuse_batch_write_begin(bool *need_fix)
19 {
20     if (*need_fix == false) {
21         esp_efuse_batch_write_begin();
22     }
23     *need_fix = true;
24 }
25 
update_efuses(bool need_fix,esp_err_t err)26 static void update_efuses(bool need_fix, esp_err_t err)
27 {
28     if (need_fix) {
29         if (err != ESP_OK) {
30             ESP_LOGE(TAG, "Can not be fixed (err=0x%x).", err);
31             esp_efuse_batch_write_cancel();
32         } else {
33             err = esp_efuse_batch_write_commit();
34             if (err != ESP_OK) {
35                 ESP_LOGE(TAG, "Error programming eFuses (err=0x%x)", err);
36                 return;
37             } else {
38                 ESP_LOGI(TAG, "Fixed");
39             }
40         }
41     }
42 }
43 #ifdef CONFIG_SECURE_BOOT_V1_ENABLED
secure_boot_v1_check(bool * need_fix)44 static esp_err_t secure_boot_v1_check(bool *need_fix)
45 {
46     esp_err_t err = ESP_OK;
47     esp_efuse_block_t block = EFUSE_BLK_SECURE_BOOT;
48     if (!esp_efuse_get_key_dis_read(block)) {
49         efuse_batch_write_begin(need_fix);
50         ESP_LOGW(TAG, "eFuse BLOCK%d should not be readable. Fixing..", block);
51         err = esp_efuse_set_key_dis_read(block);
52     }
53     if (!esp_efuse_get_key_dis_write(block)) {
54         efuse_batch_write_begin(need_fix);
55         ESP_LOGW(TAG, "eFuse BLOCK%d should not be writeable. Fixing..", block);
56         if (err == ESP_OK) {
57             err = esp_efuse_set_key_dis_write(block);
58         }
59     }
60     return err;
61 }
62 #elif SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS == 1 && CONFIG_SECURE_BOOT_V2_ENABLED
secure_boot_v2_check(bool * need_fix)63 static esp_err_t secure_boot_v2_check(bool *need_fix)
64 {
65     esp_err_t err = ESP_OK;
66     esp_efuse_block_t block = EFUSE_BLK_SECURE_BOOT;
67     if (esp_efuse_get_key_dis_read(block)) {
68         ESP_LOGE(TAG, "eFuse BLOCK%d should be readable", block);
69         abort();
70         // This code is not achievable because the bootloader will not boot an app in this state.
71         // But we keep it here just in case (any unexpected behavior).
72     }
73     if (esp_efuse_block_is_empty(block)) {
74         ESP_LOGE(TAG, "eFuse BLOCK%d should not be empty", block);
75         abort();
76         // This code is not achievable because the bootloader will not boot an app in this state.
77         // But we keep it here just in case (any unexpected behavior).
78     }
79     if (!esp_efuse_get_key_dis_write(block)) {
80         efuse_batch_write_begin(need_fix);
81         ESP_LOGW(TAG, "eFuse BLOCK%d should not be writeable. Fixing..", block);
82         err = esp_efuse_set_key_dis_write(block);
83     }
84     return err;
85 }
86 #elif SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 && CONFIG_SECURE_BOOT_V2_ENABLED
secure_boot_v2_check(bool * need_fix)87 static esp_err_t secure_boot_v2_check(bool *need_fix)
88 {
89     esp_err_t err = ESP_OK;
90     esp_efuse_purpose_t purpose[SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS] = {
91         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
92         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
93         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
94     };
95 
96     for (unsigned i = 0; i < SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS; ++i) {
97         esp_efuse_block_t block;
98         if (esp_efuse_find_purpose(purpose[i], &block)) {
99             if (!esp_efuse_get_digest_revoke(i)) {
100                 if (esp_efuse_get_key_dis_read(block)) {
101                     ESP_LOGE(TAG, "eFuse BLOCK%d should be readable", block);
102                     abort();
103                     // This state is not expected unless the eFuses have been manually misconfigured.
104                 }
105                 if (esp_efuse_block_is_empty(block)) {
106                     ESP_LOGE(TAG, "eFuse BLOCK%d should not be empty", block);
107                     abort();
108                     // This state is not expected unless the eFuses have been manually misconfigured.
109                 }
110                 if (!esp_efuse_get_key_dis_write(block)) {
111                     efuse_batch_write_begin(need_fix);
112                     ESP_LOGW(TAG, "eFuse BLOCK%d should not be writeable. Fixing..", block);
113                     if (err == ESP_OK) {
114                         err = esp_efuse_set_key_dis_write(block);
115                     }
116                 }
117             }
118             if (!esp_efuse_get_keypurpose_dis_write(block)) {
119                 efuse_batch_write_begin(need_fix);
120                 ESP_LOGW(TAG, "The KEY_PURPOSE_SECURE_BOOT_DIGEST%d should be write-protected. Fixing..", block);
121                 if (err == ESP_OK) {
122                     err = esp_efuse_set_keypurpose_dis_write(block);
123                 }
124             }
125         } else {
126             if (!esp_efuse_get_digest_revoke(i)) {
127 #ifndef CONFIG_SECURE_BOOT_ALLOW_UNUSED_DIGEST_SLOTS
128                 efuse_batch_write_begin(need_fix);
129                 ESP_LOGW(TAG, "Unused SECURE_BOOT_DIGEST%d should be revoked. Fixing..", i);
130                 if (err == ESP_OK) {
131                     err = esp_efuse_set_digest_revoke(i);
132                 }
133 #else
134                 ESP_LOGW(TAG, "Unused SECURE_BOOT_DIGEST%d should be revoked. It will not be fixed due to the config", i);
135 #endif
136             }
137         }
138     }
139     return err;
140 }
141 #endif
142 #endif // CONFIG_SECURE_BOOT
143 
144 #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
145 
rsa_check_signature_on_update_check(void)146 static void rsa_check_signature_on_update_check(void)
147 {
148     // We rely on the keys used to sign this app to verify the next app on OTA, so make sure there is at
149     // least one to avoid a stuck firmware
150     esp_image_sig_public_key_digests_t digests = { 0 };
151 
152     esp_err_t err = esp_secure_boot_get_signature_blocks_for_running_app(false, &digests);
153 
154     if (err != ESP_OK || digests.num_digests == 0) {
155         ESP_LOGE(TAG, "This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update.");
156         abort();
157     }
158 #if CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT && SECURE_BOOT_NUM_BLOCKS > 1
159     if (digests.num_digests > 1) {
160         ESP_LOGW(TAG, "App has %d signatures. Only the first position of signature blocks is used to verify any update", digests.num_digests);
161     }
162 #endif
163 }
164 #endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
165 
esp_secure_boot_init_checks(void)166 void esp_secure_boot_init_checks(void)
167 {
168 #ifdef CONFIG_SECURE_BOOT
169 
170     if (esp_secure_boot_enabled()) {
171         bool need_fix = false;
172 #ifdef CONFIG_SECURE_BOOT_V1_ENABLED
173         esp_err_t err = secure_boot_v1_check(&need_fix);
174 #else
175         esp_err_t err = secure_boot_v2_check(&need_fix);
176 #endif
177         update_efuses(need_fix, err);
178     } else {
179         ESP_LOGE(TAG, "Mismatch in secure boot settings: the app config is enabled but eFuse not");
180     }
181 #endif // CONFIG_SECURE_BOOT
182 
183 
184 #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
185     rsa_check_signature_on_update_check();
186 #endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
187 
188 }
189 #endif // not BOOTLOADER_BUILD
190