blob: 9e1aa0704621e9544df2c694eaaad94eba974299 [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 Okato54ef4842023-03-07 17:56:53 -030016#include "esp_assert.h"
17
Almir Okatoe8cbc0d2022-06-13 10:45:39 -030018#ifdef CONFIG_MCUBOOT_SERIAL
19#include "boot_serial/boot_serial.h"
20#include "serial_adapter/serial_adapter.h"
21
22const struct boot_uart_funcs boot_funcs = {
23 .read = console_read,
24 .write = console_write
25};
26#endif
27
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030028#if defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH) || defined(CONFIG_SECURE_BOOT)
29#include "esp_efuse.h"
30#endif
31#ifdef CONFIG_SECURE_BOOT
32#include "esp_secure_boot.h"
33#endif
Almir Okato14763b12021-11-25 00:45:26 -030034#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
35#include "esp_flash_encrypt.h"
36#endif
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030037
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -030038#include "esp_loader.h"
39#include "os/os_malloc.h"
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053040
Almir Okatoa1d641d2022-02-21 19:31:46 -030041#define IMAGE_INDEX_0 0
42#define IMAGE_INDEX_1 1
43
44#define PRIMARY_SLOT 0
45#define SECONDARY_SLOT 1
46
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030047#ifdef CONFIG_SECURE_BOOT
48extern esp_err_t check_and_generate_secure_boot_keys(void);
49#endif
50
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053051void do_boot(struct boot_rsp *rsp)
52{
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -030053 BOOT_LOG_INF("br_image_off = 0x%x", rsp->br_image_off);
54 BOOT_LOG_INF("ih_hdr_size = 0x%x", rsp->br_hdr->ih_hdr_size);
Almir Okatoa1d641d2022-02-21 19:31:46 -030055 int slot = (rsp->br_image_off == CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS) ? PRIMARY_SLOT : SECONDARY_SLOT;
Almir Okatoc4b30582022-05-06 14:59:43 -030056 start_cpu0_image(IMAGE_INDEX_0, slot, rsp->br_hdr->ih_hdr_size);
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053057}
Shubham Kulkarni052561d2021-07-20 11:42:44 +053058
Almir Okatoa1d641d2022-02-21 19:31:46 -030059#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
60int read_image_header(uint32_t img_index, uint32_t slot, struct image_header *img_header)
61{
62 const struct flash_area *fap;
63 int area_id;
64 int rc = 0;
65
66 area_id = flash_area_id_from_multi_image_slot(img_index, slot);
67 rc = flash_area_open(area_id, &fap);
68 if (rc != 0) {
69 rc = BOOT_EFLASH;
70 goto done;
71 }
72
73 if (flash_area_read(fap, 0, img_header, sizeof(struct image_header))) {
74 rc = BOOT_EFLASH;
75 goto done;
76 }
77
78 BOOT_LOG_INF("Image offset = 0x%x", fap->fa_off);
79 BOOT_LOG_INF("Image header size = 0x%x", img_header->ih_hdr_size);
80
81done:
82 flash_area_close(fap);
83 return rc;
84}
85
86void do_boot_appcpu(uint32_t img_index, uint32_t slot)
87{
Almir Okatoa1d641d2022-02-21 19:31:46 -030088 struct image_header img_header;
89
90 if (read_image_header(img_index, slot, &img_header) != 0) {
91 FIH_PANIC;
92 }
93
Almir Okatoc4b30582022-05-06 14:59:43 -030094 start_cpu1_image(img_index, slot, img_header.ih_hdr_size);
Almir Okatoa1d641d2022-02-21 19:31:46 -030095}
96#endif
97
Shubham Kulkarni052561d2021-07-20 11:42:44 +053098int main()
99{
Almir Okatofa173df2022-04-19 01:10:30 -0300100 if (bootloader_init() != ESP_OK) {
101 FIH_PANIC;
102 }
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300103
Almir Okato14763b12021-11-25 00:45:26 -0300104 /* Rough steps for a first boot when Secure Boot and/or Flash Encryption are still disabled on device:
105 * Secure Boot:
106 * 1) Calculate the SHA-256 hash digest of the public key and write to EFUSE.
107 * 2) Validate the application images and prepare the booting process.
108 * 3) Burn EFUSE to enable Secure Boot V2 (ABS_DONE_0).
109 * Flash Encryption:
110 * 4) Generate Flash Encryption key and write to EFUSE.
111 * 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
112 * 6) Burn EFUSE to enable Flash Encryption.
113 * 7) Reset system to ensure Flash Encryption cache resets properly.
114 */
115
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300116#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
117 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!");
118 esp_efuse_init_virtual_mode_in_flash(CONFIG_EFUSE_VIRTUAL_OFFSET, CONFIG_EFUSE_VIRTUAL_SIZE);
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530119#endif
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530120
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300121#ifdef CONFIG_SECURE_BOOT
Almir Okato14763b12021-11-25 00:45:26 -0300122 /* Steps 1 (see above for full description):
123 * 1) Compute digest of the public key.
124 */
125
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300126 BOOT_LOG_INF("enabling secure boot v2...");
127
128 bool sb_hw_enabled = esp_secure_boot_enabled();
129
130 if (sb_hw_enabled) {
131 BOOT_LOG_INF("secure boot v2 is already enabled, continuing..");
132 } else {
133 esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
134
135 esp_err_t err;
136 err = check_and_generate_secure_boot_keys();
137 if (err != ESP_OK) {
138 esp_efuse_batch_write_cancel();
139 FIH_PANIC;
140 }
141 }
142#endif
143
Almir Okatoeb6b7bf2021-09-07 17:06:35 -0300144 os_heap_init();
145
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300146 struct boot_rsp rsp;
Almir Okato14763b12021-11-25 00:45:26 -0300147
Michael Grand5047f032022-11-24 16:49:56 +0100148 FIH_DECLARE(fih_rc, FIH_FAILURE);
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300149
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300150#ifdef CONFIG_MCUBOOT_SERIAL
151 boot_console_init();
152 if (boot_serial_detect_pin()) {
153 BOOT_LOG_INF("Enter the serial recovery mode");
154 boot_serial_start(&boot_funcs);
155 }
156#endif
157
Almir Okato14763b12021-11-25 00:45:26 -0300158 /* Step 2 (see above for full description):
159 * 2) MCUboot validates the application images and prepares the booting process.
160 */
161
Almir Okatoa1d641d2022-02-21 19:31:46 -0300162 /* MCUboot's boot_go validates and checks all images for update and returns
163 * the load information for booting the main image
164 */
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530165 FIH_CALL(boot_go, fih_rc, &rsp);
Michael Grand5047f032022-11-24 16:49:56 +0100166 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -0300167 BOOT_LOG_ERR("Unable to find bootable image");
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300168#ifdef CONFIG_SECURE_BOOT
169 esp_efuse_batch_write_cancel();
170#endif
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530171 FIH_PANIC;
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530172 }
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300173
174#ifdef CONFIG_SECURE_BOOT
Almir Okato14763b12021-11-25 00:45:26 -0300175 /* Step 3 (see above for full description):
176 * 3) Burn EFUSE to enable Secure Boot V2.
177 */
178
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300179 if (!sb_hw_enabled) {
180 BOOT_LOG_INF("blowing secure boot efuse...");
181 esp_err_t err;
182 err = esp_secure_boot_enable_secure_features();
183 if (err != ESP_OK) {
184 esp_efuse_batch_write_cancel();
185 FIH_PANIC;
186 }
187
188 err = esp_efuse_batch_write_commit();
189 if (err != ESP_OK) {
190 BOOT_LOG_ERR("Error programming security eFuses (err=0x%x).", err);
191 FIH_PANIC;
192 }
193
194#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
195 assert(esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE));
196#endif
197
198 assert(esp_secure_boot_enabled());
199 BOOT_LOG_INF("Secure boot permanently enabled");
200 }
201#endif
202
Almir Okato14763b12021-11-25 00:45:26 -0300203#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
204 /* Step 4, 5 & 6 (see above for full description):
205 * 4) Generate Flash Encryption key and write to EFUSE.
206 * 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
207 * 6) Burn EFUSE to enable flash encryption
208 */
209
210 int rc;
211
212 BOOT_LOG_INF("Checking flash encryption...");
213 bool flash_encryption_enabled = esp_flash_encryption_enabled();
214 rc = esp_flash_encrypt_check_and_update();
215 if (rc != ESP_OK) {
216 BOOT_LOG_ERR("Flash encryption check failed (%d).", rc);
217 FIH_PANIC;
218 }
219
220 /* Step 7 (see above for full description):
221 * 7) Reset system to ensure flash encryption cache resets properly.
222 */
223 if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
224 BOOT_LOG_INF("Resetting with flash encryption enabled...");
225 bootloader_reset();
226 }
227#endif
228
229 BOOT_LOG_INF("Disabling RNG early entropy source...");
230 bootloader_random_disable();
231
Almir Okatoa1d641d2022-02-21 19:31:46 -0300232#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
233 /* Multi image independent boot
234 * Boot on the second processor happens before the image0 boot
235 */
236 do_boot_appcpu(IMAGE_INDEX_1, PRIMARY_SLOT);
237#endif
238
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530239 do_boot(&rsp);
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300240
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530241 while(1);
242}