1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8
9 #include "esp_attr.h"
10 #include "esp_types.h"
11 #include "esp_log.h"
12
13 #include "esp32/rom/cache.h"
14 #include "esp32/rom/secure_boot.h"
15
16 #include "soc/rtc_periph.h"
17 #include "bootloader_utility.h"
18
19 #include "sdkconfig.h"
20
21 #include "bootloader_flash_priv.h"
22 #include "bootloader_random.h"
23 #include "esp_image_format.h"
24 #include "esp_secure_boot.h"
25 #include "esp_flash_encrypt.h"
26 #include "esp_efuse.h"
27 #include "esp_efuse_table.h"
28
29 /* The following API implementations are used only when called
30 * from the bootloader code.
31 */
32
33 #ifdef CONFIG_SECURE_BOOT_V1_ENABLED
34 static const char *TAG = "secure_boot_v1";
35 /**
36 * @function : secure_boot_generate
37 * @description: generate boot digest (aka "abstract") & iv
38 *
39 * @inputs: image_len - length of image to calculate digest for
40 */
secure_boot_generate(uint32_t image_len)41 static bool secure_boot_generate(uint32_t image_len){
42 esp_err_t err;
43 esp_secure_boot_iv_digest_t digest;
44 const uint32_t *image;
45
46 /* hardware secure boot engine only takes full blocks, so round up the
47 image length. The additional data should all be 0xFF (or the appended SHA, if it falls in the same block).
48 */
49 if (image_len % sizeof(digest.iv) != 0) {
50 image_len = (image_len / sizeof(digest.iv) + 1) * sizeof(digest.iv);
51 }
52 ets_secure_boot_start();
53 ets_secure_boot_rd_iv((uint32_t *)digest.iv);
54 ets_secure_boot_hash(NULL);
55 /* iv stored in sec 0 */
56 err = bootloader_flash_erase_sector(0);
57 if (err != ESP_OK)
58 {
59 ESP_LOGE(TAG, "SPI erase failed: 0x%x", err);
60 return false;
61 }
62
63 /* generate digest from image contents */
64 image = bootloader_mmap(ESP_BOOTLOADER_OFFSET, image_len);
65 if (!image) {
66 ESP_LOGE(TAG, "bootloader_mmap(0x1000, 0x%x) failed", image_len);
67 return false;
68 }
69 for (size_t i = 0; i < image_len; i+= sizeof(digest.iv)) {
70 ets_secure_boot_hash(&image[i/sizeof(uint32_t)]);
71 }
72 bootloader_munmap(image);
73
74 ets_secure_boot_obtain();
75 ets_secure_boot_rd_abstract((uint32_t *)digest.digest);
76 ets_secure_boot_finish();
77
78 ESP_LOGD(TAG, "write iv+digest to flash");
79 err = bootloader_flash_write(FLASH_OFFS_SECURE_BOOT_IV_DIGEST, &digest,
80 sizeof(digest), esp_flash_encryption_enabled());
81 if (err != ESP_OK) {
82 ESP_LOGE(TAG, "SPI write failed: 0x%x", err);
83 return false;
84 }
85 Cache_Read_Enable(0);
86 return true;
87 }
88
esp_secure_boot_generate_digest(void)89 esp_err_t esp_secure_boot_generate_digest(void)
90 {
91 esp_err_t err;
92 if (esp_secure_boot_enabled()) {
93 ESP_LOGI(TAG, "bootloader secure boot is already enabled."
94 " No need to generate digest. continuing..");
95 return ESP_OK;
96 }
97
98 esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_SECURE_BOOT);
99 if (coding_scheme != EFUSE_CODING_SCHEME_NONE && coding_scheme != EFUSE_CODING_SCHEME_3_4) {
100 ESP_LOGE(TAG, "Unknown/unsupported CODING_SCHEME value 0x%x", coding_scheme);
101 return ESP_ERR_NOT_SUPPORTED;
102 }
103
104 /* Verify the bootloader */
105 esp_image_metadata_t bootloader_data = { 0 };
106 err = esp_image_verify_bootloader_data(&bootloader_data);
107 if (err != ESP_OK) {
108 ESP_LOGE(TAG, "bootloader image appears invalid! error %d", err);
109 return err;
110 }
111
112 bool dis_write = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_BLK2);
113 bool dis_read = esp_efuse_read_field_bit(ESP_EFUSE_RD_DIS_BLK2);
114 bool key_is_empty = esp_efuse_block_is_empty(EFUSE_BLK_SECURE_BOOT);
115
116 /* Generate secure boot key and keep in EFUSE */
117 if (!dis_read && !dis_write && key_is_empty) {
118 ESP_LOGI(TAG, "Generating new secure boot key...");
119 uint32_t key[8];
120 size_t key_size = 256;
121 if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
122 key_size = 192;
123 }
124 bootloader_fill_random(key, key_size / 8);
125 esp_efuse_write_block(EFUSE_BLK_SECURE_BOOT, key, 0, key_size);
126 } else {
127 ESP_LOGW(TAG, "Using pre-loaded secure boot key in EFUSE block 2");
128 }
129
130 /* Generate secure boot digest using programmed key in EFUSE */
131 ESP_LOGI(TAG, "Generating secure boot digest...");
132 uint32_t image_len = bootloader_data.image_len;
133 if(bootloader_data.image.hash_appended) {
134 /* Secure boot digest doesn't cover the hash */
135 image_len -= ESP_IMAGE_HASH_LEN;
136 }
137 if (false == secure_boot_generate(image_len)){
138 ESP_LOGE(TAG, "secure boot generation failed");
139 return ESP_FAIL;
140 }
141 ESP_LOGI(TAG, "Digest generation complete.");
142
143 return ESP_OK;
144 }
145
esp_secure_boot_permanently_enable(void)146 esp_err_t esp_secure_boot_permanently_enable(void)
147 {
148 if (esp_secure_boot_enabled()) {
149 ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing..");
150 return ESP_OK;
151 }
152
153 bool dis_read = esp_efuse_read_field_bit(ESP_EFUSE_RD_DIS_BLK2);
154 bool dis_write = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_BLK2);
155 if (dis_read != dis_write) {
156 ESP_LOGE(TAG, "Pre-loaded key is not %s %s protected. Refusing to blow secure boot efuse.",
157 (!dis_read) ? "read,":" ",
158 (!dis_read) ? "write":" ");
159 return ESP_ERR_INVALID_STATE;
160 }
161 esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
162
163 ESP_LOGI(TAG, "blowing secure boot efuse...");
164 esp_err_t err = esp_secure_boot_enable_secure_features();
165 if (err != ESP_OK) {
166 esp_efuse_batch_write_cancel();
167 return err;
168 }
169
170 err = esp_efuse_batch_write_commit();
171 if (err != ESP_OK) {
172 ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
173 return err;
174 }
175
176 assert(esp_secure_boot_enabled());
177
178 ESP_LOGI(TAG, "secure boot is now enabled for bootloader image");
179 return ESP_OK;
180 }
181 #endif // CONFIG_SECURE_BOOT_V1_ENABLED
182