blob: 6e59b006fead542d9404901c82206f69d255efd8 [file] [log] [blame]
Shubham Kulkarni052561d2021-07-20 11:42:44 +05301/*
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -03002 * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
Shubham Kulkarni052561d2021-07-20 11:42:44 +05303 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include <bootutil/bootutil.h>
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -03008#include <bootutil/bootutil_log.h>
9#include <bootutil/fault_injection_hardening.h>
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053010#include <bootutil/image.h>
11
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -030012#include "bootloader_init.h"
Almir Okato14763b12021-11-25 00:45:26 -030013#include "bootloader_utility.h"
14#include "bootloader_random.h"
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053015
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030016#if defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH) || defined(CONFIG_SECURE_BOOT)
17#include "esp_efuse.h"
18#endif
19#ifdef CONFIG_SECURE_BOOT
20#include "esp_secure_boot.h"
21#endif
Almir Okato14763b12021-11-25 00:45:26 -030022#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
23#include "esp_flash_encrypt.h"
24#endif
Almir Okatoa1d641d2022-02-21 19:31:46 -030025#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
26#include "app_cpu_start.h"
27#endif
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030028
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -030029#include "esp_loader.h"
30#include "os/os_malloc.h"
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053031
Almir Okatoa1d641d2022-02-21 19:31:46 -030032#define IMAGE_INDEX_0 0
33#define IMAGE_INDEX_1 1
34
35#define PRIMARY_SLOT 0
36#define SECONDARY_SLOT 1
37
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030038#ifdef CONFIG_SECURE_BOOT
39extern esp_err_t check_and_generate_secure_boot_keys(void);
40#endif
41
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053042void do_boot(struct boot_rsp *rsp)
43{
Almir Okatoa1d641d2022-02-21 19:31:46 -030044 unsigned int entry_addr;
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -030045 BOOT_LOG_INF("br_image_off = 0x%x", rsp->br_image_off);
46 BOOT_LOG_INF("ih_hdr_size = 0x%x", rsp->br_hdr->ih_hdr_size);
Almir Okatoa1d641d2022-02-21 19:31:46 -030047 int slot = (rsp->br_image_off == CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS) ? PRIMARY_SLOT : SECONDARY_SLOT;
48 esp_app_image_load(IMAGE_INDEX_0, slot, rsp->br_hdr->ih_hdr_size, &entry_addr);
49 ((void (*)(void))entry_addr)(); /* Call to application entry address should not return */
50 FIH_PANIC; /* It should not get here */
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053051}
Shubham Kulkarni052561d2021-07-20 11:42:44 +053052
Almir Okatoa1d641d2022-02-21 19:31:46 -030053#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
54int read_image_header(uint32_t img_index, uint32_t slot, struct image_header *img_header)
55{
56 const struct flash_area *fap;
57 int area_id;
58 int rc = 0;
59
60 area_id = flash_area_id_from_multi_image_slot(img_index, slot);
61 rc = flash_area_open(area_id, &fap);
62 if (rc != 0) {
63 rc = BOOT_EFLASH;
64 goto done;
65 }
66
67 if (flash_area_read(fap, 0, img_header, sizeof(struct image_header))) {
68 rc = BOOT_EFLASH;
69 goto done;
70 }
71
72 BOOT_LOG_INF("Image offset = 0x%x", fap->fa_off);
73 BOOT_LOG_INF("Image header size = 0x%x", img_header->ih_hdr_size);
74
75done:
76 flash_area_close(fap);
77 return rc;
78}
79
80void do_boot_appcpu(uint32_t img_index, uint32_t slot)
81{
82 unsigned int entry_addr;
83 struct image_header img_header;
84
85 if (read_image_header(img_index, slot, &img_header) != 0) {
86 FIH_PANIC;
87 }
88
89 esp_app_image_load(img_index, slot, img_header.ih_hdr_size, &entry_addr);
90 appcpu_start(entry_addr);
91}
92#endif
93
Shubham Kulkarni052561d2021-07-20 11:42:44 +053094int main()
95{
Almir Okatofa173df2022-04-19 01:10:30 -030096 if (bootloader_init() != ESP_OK) {
97 FIH_PANIC;
98 }
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030099
Almir Okato14763b12021-11-25 00:45:26 -0300100 BOOT_LOG_INF("Enabling RNG early entropy source...");
101 bootloader_random_enable();
102
103 /* Rough steps for a first boot when Secure Boot and/or Flash Encryption are still disabled on device:
104 * Secure Boot:
105 * 1) Calculate the SHA-256 hash digest of the public key and write to EFUSE.
106 * 2) Validate the application images and prepare the booting process.
107 * 3) Burn EFUSE to enable Secure Boot V2 (ABS_DONE_0).
108 * Flash Encryption:
109 * 4) Generate Flash Encryption key and write to EFUSE.
110 * 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
111 * 6) Burn EFUSE to enable Flash Encryption.
112 * 7) Reset system to ensure Flash Encryption cache resets properly.
113 */
114
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300115#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
116 BOOT_LOG_WRN("eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
117 esp_efuse_init_virtual_mode_in_flash(CONFIG_EFUSE_VIRTUAL_OFFSET, CONFIG_EFUSE_VIRTUAL_SIZE);
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530118#endif
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530119
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300120#ifdef CONFIG_SECURE_BOOT
Almir Okato14763b12021-11-25 00:45:26 -0300121 /* Steps 1 (see above for full description):
122 * 1) Compute digest of the public key.
123 */
124
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300125 BOOT_LOG_INF("enabling secure boot v2...");
126
127 bool sb_hw_enabled = esp_secure_boot_enabled();
128
129 if (sb_hw_enabled) {
130 BOOT_LOG_INF("secure boot v2 is already enabled, continuing..");
131 } else {
132 esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
133
134 esp_err_t err;
135 err = check_and_generate_secure_boot_keys();
136 if (err != ESP_OK) {
137 esp_efuse_batch_write_cancel();
138 FIH_PANIC;
139 }
140 }
141#endif
142
143 BOOT_LOG_INF("*** Booting MCUboot build %s ***", MCUBOOT_VER);
144
Almir Okatoeb6b7bf2021-09-07 17:06:35 -0300145 os_heap_init();
146
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300147 struct boot_rsp rsp;
Almir Okato14763b12021-11-25 00:45:26 -0300148
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530149 fih_int fih_rc = FIH_FAILURE;
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300150
Almir Okato14763b12021-11-25 00:45:26 -0300151 /* Step 2 (see above for full description):
152 * 2) MCUboot validates the application images and prepares the booting process.
153 */
154
Almir Okatoa1d641d2022-02-21 19:31:46 -0300155 /* MCUboot's boot_go validates and checks all images for update and returns
156 * the load information for booting the main image
157 */
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530158 FIH_CALL(boot_go, fih_rc, &rsp);
159 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -0300160 BOOT_LOG_ERR("Unable to find bootable image");
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300161#ifdef CONFIG_SECURE_BOOT
162 esp_efuse_batch_write_cancel();
163#endif
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530164 FIH_PANIC;
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530165 }
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300166
167#ifdef CONFIG_SECURE_BOOT
Almir Okato14763b12021-11-25 00:45:26 -0300168 /* Step 3 (see above for full description):
169 * 3) Burn EFUSE to enable Secure Boot V2.
170 */
171
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300172 if (!sb_hw_enabled) {
173 BOOT_LOG_INF("blowing secure boot efuse...");
174 esp_err_t err;
175 err = esp_secure_boot_enable_secure_features();
176 if (err != ESP_OK) {
177 esp_efuse_batch_write_cancel();
178 FIH_PANIC;
179 }
180
181 err = esp_efuse_batch_write_commit();
182 if (err != ESP_OK) {
183 BOOT_LOG_ERR("Error programming security eFuses (err=0x%x).", err);
184 FIH_PANIC;
185 }
186
187#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
188 assert(esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE));
189#endif
190
191 assert(esp_secure_boot_enabled());
192 BOOT_LOG_INF("Secure boot permanently enabled");
193 }
194#endif
195
Almir Okato14763b12021-11-25 00:45:26 -0300196#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
197 /* Step 4, 5 & 6 (see above for full description):
198 * 4) Generate Flash Encryption key and write to EFUSE.
199 * 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
200 * 6) Burn EFUSE to enable flash encryption
201 */
202
203 int rc;
204
205 BOOT_LOG_INF("Checking flash encryption...");
206 bool flash_encryption_enabled = esp_flash_encryption_enabled();
207 rc = esp_flash_encrypt_check_and_update();
208 if (rc != ESP_OK) {
209 BOOT_LOG_ERR("Flash encryption check failed (%d).", rc);
210 FIH_PANIC;
211 }
212
213 /* Step 7 (see above for full description):
214 * 7) Reset system to ensure flash encryption cache resets properly.
215 */
216 if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
217 BOOT_LOG_INF("Resetting with flash encryption enabled...");
218 bootloader_reset();
219 }
220#endif
221
222 BOOT_LOG_INF("Disabling RNG early entropy source...");
223 bootloader_random_disable();
224
Almir Okatoa1d641d2022-02-21 19:31:46 -0300225#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
226 /* Multi image independent boot
227 * Boot on the second processor happens before the image0 boot
228 */
229 do_boot_appcpu(IMAGE_INDEX_1, PRIMARY_SLOT);
230#endif
231
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530232 do_boot(&rsp);
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300233
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530234 while(1);
235}