blob: 2cfe114504b1f0f77281651f9ec5f164be52bc41 [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
Almir Okatoe8cbc0d2022-06-13 10:45:39 -030016#ifdef CONFIG_MCUBOOT_SERIAL
17#include "boot_serial/boot_serial.h"
18#include "serial_adapter/serial_adapter.h"
19
20const struct boot_uart_funcs boot_funcs = {
21 .read = console_read,
22 .write = console_write
23};
24#endif
25
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030026#if defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH) || defined(CONFIG_SECURE_BOOT)
27#include "esp_efuse.h"
28#endif
29#ifdef CONFIG_SECURE_BOOT
30#include "esp_secure_boot.h"
31#endif
Almir Okato14763b12021-11-25 00:45:26 -030032#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
33#include "esp_flash_encrypt.h"
34#endif
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030035
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -030036#include "esp_loader.h"
37#include "os/os_malloc.h"
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053038
Almir Okatoa1d641d2022-02-21 19:31:46 -030039#define IMAGE_INDEX_0 0
40#define IMAGE_INDEX_1 1
41
42#define PRIMARY_SLOT 0
43#define SECONDARY_SLOT 1
44
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030045#ifdef CONFIG_SECURE_BOOT
46extern esp_err_t check_and_generate_secure_boot_keys(void);
47#endif
48
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053049void do_boot(struct boot_rsp *rsp)
50{
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -030051 BOOT_LOG_INF("br_image_off = 0x%x", rsp->br_image_off);
52 BOOT_LOG_INF("ih_hdr_size = 0x%x", rsp->br_hdr->ih_hdr_size);
Almir Okatoa1d641d2022-02-21 19:31:46 -030053 int slot = (rsp->br_image_off == CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS) ? PRIMARY_SLOT : SECONDARY_SLOT;
Almir Okatoc4b30582022-05-06 14:59:43 -030054 start_cpu0_image(IMAGE_INDEX_0, slot, rsp->br_hdr->ih_hdr_size);
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053055}
Shubham Kulkarni052561d2021-07-20 11:42:44 +053056
Almir Okatoa1d641d2022-02-21 19:31:46 -030057#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
58int read_image_header(uint32_t img_index, uint32_t slot, struct image_header *img_header)
59{
60 const struct flash_area *fap;
61 int area_id;
62 int rc = 0;
63
64 area_id = flash_area_id_from_multi_image_slot(img_index, slot);
65 rc = flash_area_open(area_id, &fap);
66 if (rc != 0) {
67 rc = BOOT_EFLASH;
68 goto done;
69 }
70
71 if (flash_area_read(fap, 0, img_header, sizeof(struct image_header))) {
72 rc = BOOT_EFLASH;
73 goto done;
74 }
75
76 BOOT_LOG_INF("Image offset = 0x%x", fap->fa_off);
77 BOOT_LOG_INF("Image header size = 0x%x", img_header->ih_hdr_size);
78
79done:
80 flash_area_close(fap);
81 return rc;
82}
83
84void do_boot_appcpu(uint32_t img_index, uint32_t slot)
85{
Almir Okatoa1d641d2022-02-21 19:31:46 -030086 struct image_header img_header;
87
88 if (read_image_header(img_index, slot, &img_header) != 0) {
89 FIH_PANIC;
90 }
91
Almir Okatoc4b30582022-05-06 14:59:43 -030092 start_cpu1_image(img_index, slot, img_header.ih_hdr_size);
Almir Okatoa1d641d2022-02-21 19:31:46 -030093}
94#endif
95
Shubham Kulkarni052561d2021-07-20 11:42:44 +053096int main()
97{
Almir Okatofa173df2022-04-19 01:10:30 -030098 if (bootloader_init() != ESP_OK) {
99 FIH_PANIC;
100 }
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300101
Almir Okato14763b12021-11-25 00:45:26 -0300102 BOOT_LOG_INF("Enabling RNG early entropy source...");
103 bootloader_random_enable();
104
105 /* Rough steps for a first boot when Secure Boot and/or Flash Encryption are still disabled on device:
106 * Secure Boot:
107 * 1) Calculate the SHA-256 hash digest of the public key and write to EFUSE.
108 * 2) Validate the application images and prepare the booting process.
109 * 3) Burn EFUSE to enable Secure Boot V2 (ABS_DONE_0).
110 * Flash Encryption:
111 * 4) Generate Flash Encryption key and write to EFUSE.
112 * 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
113 * 6) Burn EFUSE to enable Flash Encryption.
114 * 7) Reset system to ensure Flash Encryption cache resets properly.
115 */
116
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300117#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
118 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!");
119 esp_efuse_init_virtual_mode_in_flash(CONFIG_EFUSE_VIRTUAL_OFFSET, CONFIG_EFUSE_VIRTUAL_SIZE);
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530120#endif
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530121
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300122#ifdef CONFIG_SECURE_BOOT
Almir Okato14763b12021-11-25 00:45:26 -0300123 /* Steps 1 (see above for full description):
124 * 1) Compute digest of the public key.
125 */
126
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300127 BOOT_LOG_INF("enabling secure boot v2...");
128
129 bool sb_hw_enabled = esp_secure_boot_enabled();
130
131 if (sb_hw_enabled) {
132 BOOT_LOG_INF("secure boot v2 is already enabled, continuing..");
133 } else {
134 esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
135
136 esp_err_t err;
137 err = check_and_generate_secure_boot_keys();
138 if (err != ESP_OK) {
139 esp_efuse_batch_write_cancel();
140 FIH_PANIC;
141 }
142 }
143#endif
144
145 BOOT_LOG_INF("*** Booting MCUboot build %s ***", MCUBOOT_VER);
146
Almir Okatoeb6b7bf2021-09-07 17:06:35 -0300147 os_heap_init();
148
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300149 struct boot_rsp rsp;
Almir Okato14763b12021-11-25 00:45:26 -0300150
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530151 fih_int fih_rc = FIH_FAILURE;
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300152
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300153#ifdef CONFIG_MCUBOOT_SERIAL
154 boot_console_init();
155 if (boot_serial_detect_pin()) {
156 BOOT_LOG_INF("Enter the serial recovery mode");
157 boot_serial_start(&boot_funcs);
158 }
159#endif
160
Almir Okato14763b12021-11-25 00:45:26 -0300161 /* Step 2 (see above for full description):
162 * 2) MCUboot validates the application images and prepares the booting process.
163 */
164
Almir Okatoa1d641d2022-02-21 19:31:46 -0300165 /* MCUboot's boot_go validates and checks all images for update and returns
166 * the load information for booting the main image
167 */
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530168 FIH_CALL(boot_go, fih_rc, &rsp);
169 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -0300170 BOOT_LOG_ERR("Unable to find bootable image");
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300171#ifdef CONFIG_SECURE_BOOT
172 esp_efuse_batch_write_cancel();
173#endif
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530174 FIH_PANIC;
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530175 }
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300176
177#ifdef CONFIG_SECURE_BOOT
Almir Okato14763b12021-11-25 00:45:26 -0300178 /* Step 3 (see above for full description):
179 * 3) Burn EFUSE to enable Secure Boot V2.
180 */
181
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300182 if (!sb_hw_enabled) {
183 BOOT_LOG_INF("blowing secure boot efuse...");
184 esp_err_t err;
185 err = esp_secure_boot_enable_secure_features();
186 if (err != ESP_OK) {
187 esp_efuse_batch_write_cancel();
188 FIH_PANIC;
189 }
190
191 err = esp_efuse_batch_write_commit();
192 if (err != ESP_OK) {
193 BOOT_LOG_ERR("Error programming security eFuses (err=0x%x).", err);
194 FIH_PANIC;
195 }
196
197#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
198 assert(esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE));
199#endif
200
201 assert(esp_secure_boot_enabled());
202 BOOT_LOG_INF("Secure boot permanently enabled");
203 }
204#endif
205
Almir Okato14763b12021-11-25 00:45:26 -0300206#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
207 /* Step 4, 5 & 6 (see above for full description):
208 * 4) Generate Flash Encryption key and write to EFUSE.
209 * 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
210 * 6) Burn EFUSE to enable flash encryption
211 */
212
213 int rc;
214
215 BOOT_LOG_INF("Checking flash encryption...");
216 bool flash_encryption_enabled = esp_flash_encryption_enabled();
217 rc = esp_flash_encrypt_check_and_update();
218 if (rc != ESP_OK) {
219 BOOT_LOG_ERR("Flash encryption check failed (%d).", rc);
220 FIH_PANIC;
221 }
222
223 /* Step 7 (see above for full description):
224 * 7) Reset system to ensure flash encryption cache resets properly.
225 */
226 if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
227 BOOT_LOG_INF("Resetting with flash encryption enabled...");
228 bootloader_reset();
229 }
230#endif
231
232 BOOT_LOG_INF("Disabling RNG early entropy source...");
233 bootloader_random_disable();
234
Almir Okatoa1d641d2022-02-21 19:31:46 -0300235#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
236 /* Multi image independent boot
237 * Boot on the second processor happens before the image0 boot
238 */
239 do_boot_appcpu(IMAGE_INDEX_1, PRIMARY_SLOT);
240#endif
241
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530242 do_boot(&rsp);
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300243
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530244 while(1);
245}