blob: 6fe93a2431ddd0544ac3f9bb2ad54c3862439eeb [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{
Shubham Kulkarni8787bb02021-07-20 11:46:03 +053096 bootloader_init();
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -030097
Almir Okato14763b12021-11-25 00:45:26 -030098 BOOT_LOG_INF("Enabling RNG early entropy source...");
99 bootloader_random_enable();
100
101 /* Rough steps for a first boot when Secure Boot and/or Flash Encryption are still disabled on device:
102 * Secure Boot:
103 * 1) Calculate the SHA-256 hash digest of the public key and write to EFUSE.
104 * 2) Validate the application images and prepare the booting process.
105 * 3) Burn EFUSE to enable Secure Boot V2 (ABS_DONE_0).
106 * Flash Encryption:
107 * 4) Generate Flash Encryption key and write to EFUSE.
108 * 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
109 * 6) Burn EFUSE to enable Flash Encryption.
110 * 7) Reset system to ensure Flash Encryption cache resets properly.
111 */
112
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300113#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
114 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!");
115 esp_efuse_init_virtual_mode_in_flash(CONFIG_EFUSE_VIRTUAL_OFFSET, CONFIG_EFUSE_VIRTUAL_SIZE);
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530116#endif
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530117
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300118#ifdef CONFIG_SECURE_BOOT
Almir Okato14763b12021-11-25 00:45:26 -0300119 /* Steps 1 (see above for full description):
120 * 1) Compute digest of the public key.
121 */
122
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300123 BOOT_LOG_INF("enabling secure boot v2...");
124
125 bool sb_hw_enabled = esp_secure_boot_enabled();
126
127 if (sb_hw_enabled) {
128 BOOT_LOG_INF("secure boot v2 is already enabled, continuing..");
129 } else {
130 esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
131
132 esp_err_t err;
133 err = check_and_generate_secure_boot_keys();
134 if (err != ESP_OK) {
135 esp_efuse_batch_write_cancel();
136 FIH_PANIC;
137 }
138 }
139#endif
140
141 BOOT_LOG_INF("*** Booting MCUboot build %s ***", MCUBOOT_VER);
142
Almir Okatoeb6b7bf2021-09-07 17:06:35 -0300143 os_heap_init();
144
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300145 struct boot_rsp rsp;
Almir Okato14763b12021-11-25 00:45:26 -0300146
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530147 fih_int fih_rc = FIH_FAILURE;
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300148
Almir Okato14763b12021-11-25 00:45:26 -0300149 /* Step 2 (see above for full description):
150 * 2) MCUboot validates the application images and prepares the booting process.
151 */
152
Almir Okatoa1d641d2022-02-21 19:31:46 -0300153 /* MCUboot's boot_go validates and checks all images for update and returns
154 * the load information for booting the main image
155 */
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530156 FIH_CALL(boot_go, fih_rc, &rsp);
157 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
Gustavo Henrique Niheid985d222021-11-12 14:21:12 -0300158 BOOT_LOG_ERR("Unable to find bootable image");
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300159#ifdef CONFIG_SECURE_BOOT
160 esp_efuse_batch_write_cancel();
161#endif
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530162 FIH_PANIC;
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530163 }
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300164
165#ifdef CONFIG_SECURE_BOOT
Almir Okato14763b12021-11-25 00:45:26 -0300166 /* Step 3 (see above for full description):
167 * 3) Burn EFUSE to enable Secure Boot V2.
168 */
169
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300170 if (!sb_hw_enabled) {
171 BOOT_LOG_INF("blowing secure boot efuse...");
172 esp_err_t err;
173 err = esp_secure_boot_enable_secure_features();
174 if (err != ESP_OK) {
175 esp_efuse_batch_write_cancel();
176 FIH_PANIC;
177 }
178
179 err = esp_efuse_batch_write_commit();
180 if (err != ESP_OK) {
181 BOOT_LOG_ERR("Error programming security eFuses (err=0x%x).", err);
182 FIH_PANIC;
183 }
184
185#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
186 assert(esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE));
187#endif
188
189 assert(esp_secure_boot_enabled());
190 BOOT_LOG_INF("Secure boot permanently enabled");
191 }
192#endif
193
Almir Okato14763b12021-11-25 00:45:26 -0300194#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
195 /* Step 4, 5 & 6 (see above for full description):
196 * 4) Generate Flash Encryption key and write to EFUSE.
197 * 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
198 * 6) Burn EFUSE to enable flash encryption
199 */
200
201 int rc;
202
203 BOOT_LOG_INF("Checking flash encryption...");
204 bool flash_encryption_enabled = esp_flash_encryption_enabled();
205 rc = esp_flash_encrypt_check_and_update();
206 if (rc != ESP_OK) {
207 BOOT_LOG_ERR("Flash encryption check failed (%d).", rc);
208 FIH_PANIC;
209 }
210
211 /* Step 7 (see above for full description):
212 * 7) Reset system to ensure flash encryption cache resets properly.
213 */
214 if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
215 BOOT_LOG_INF("Resetting with flash encryption enabled...");
216 bootloader_reset();
217 }
218#endif
219
220 BOOT_LOG_INF("Disabling RNG early entropy source...");
221 bootloader_random_disable();
222
Almir Okatoa1d641d2022-02-21 19:31:46 -0300223#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
224 /* Multi image independent boot
225 * Boot on the second processor happens before the image0 boot
226 */
227 do_boot_appcpu(IMAGE_INDEX_1, PRIMARY_SLOT);
228#endif
229
Shubham Kulkarni8787bb02021-07-20 11:46:03 +0530230 do_boot(&rsp);
Gustavo Henrique Nihei523ef3f2021-11-12 17:53:18 -0300231
Shubham Kulkarni052561d2021-07-20 11:42:44 +0530232 while(1);
233}