1 /*
2 * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include "sdkconfig.h"
9 #include "esp_log.h"
10 #include "esp_secure_boot.h"
11 #include "bootloader_flash_priv.h"
12 #include "bootloader_sha.h"
13 #include "bootloader_utility.h"
14 #include "esp_image_format.h"
15 #include "esp_efuse.h"
16 #include "esp_efuse_table.h"
17 #include "secure_boot_signature_priv.h"
18
19
20 /* The following API implementations are used only when called
21 * from the bootloader code.
22 */
23
24 #ifdef CONFIG_SECURE_BOOT_V2_ENABLED
25
26 #define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
27 static const char *TAG = "secure_boot_v2";
28
29 /* A signature block is valid when it has correct magic byte, crc and image digest. */
validate_signature_block(const ets_secure_boot_sig_block_t * block,int block_num,const uint8_t * image_digest)30 static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block, int block_num, const uint8_t *image_digest)
31 {
32 if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC) {
33 // All signature blocks have been parsed, no new signature block present.
34 ESP_LOGD(TAG, "Signature block(%d) invalid/absent.", block_num);
35 return ESP_FAIL;
36 }
37 if (block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) {
38 ESP_LOGE(TAG, "Magic byte correct but incorrect crc.");
39 return ESP_FAIL;
40 }
41 if (memcmp(image_digest, block->image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
42 ESP_LOGE(TAG, "Magic byte & CRC correct but incorrect image digest.");
43 return ESP_FAIL;
44 } else {
45 ESP_LOGD(TAG, "valid signature block(%d) found", block_num);
46 return ESP_OK;
47 }
48 return ESP_FAIL;
49 }
50
51 /* Generates the public key digests of the valid public keys in an image's
52 signature block, verifies each signature, and stores the key digests in the
53 public_key_digests structure.
54
55 @param flash_offset Image offset in flash
56 @param flash_size Image size in flash (not including signature block)
57 @param[out] public_key_digests Pointer to structure to hold the key digests for valid sig blocks
58
59
60 Note that this function doesn't read any eFuses, so it doesn't know if the
61 keys are ultimately trusted by the hardware or not
62
63 @return - ESP_OK if no signatures failed to verify, or if no valid signature blocks are found at all.
64 - ESP_FAIL if there's a valid signature block that doesn't verify using the included public key (unexpected!)
65 */
s_calculate_image_public_key_digests(uint32_t flash_offset,uint32_t flash_size,esp_image_sig_public_key_digests_t * public_key_digests)66 static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, esp_image_sig_public_key_digests_t *public_key_digests)
67 {
68 esp_err_t ret;
69 uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
70 uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
71 size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
72
73 ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%x (sig block offset 0x%x)", flash_offset, sig_block_addr);
74
75 bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
76
77 ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
78 if (ret != ESP_OK) {
79 ESP_LOGE(TAG, "error generating image digest, %d", ret);
80 return ret;
81 }
82
83 ESP_LOGD(TAG, "reading signature(s)");
84 const ets_secure_boot_signature_t *signatures = bootloader_mmap(sig_block_addr, sizeof(ets_secure_boot_signature_t));
85 if (signatures == NULL) {
86 ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", sig_block_addr, sizeof(ets_secure_boot_signature_t));
87 return ESP_FAIL;
88 }
89
90 /* Validating Signature block */
91 for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
92 const ets_secure_boot_sig_block_t *block = &signatures->block[i];
93
94 ret = validate_signature_block(block, i, image_digest);
95 if (ret != ESP_OK) {
96 ret = ESP_OK; // past the last valid signature block
97 break;
98 }
99
100 /* Generating the SHA of the public key components in the signature block */
101 bootloader_sha256_handle_t sig_block_sha;
102 sig_block_sha = bootloader_sha256_start();
103 #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
104 bootloader_sha256_data(sig_block_sha, &block->key, sizeof(block->key));
105 #elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
106 bootloader_sha256_data(sig_block_sha, &block->ecdsa.key, sizeof(block->ecdsa.key));
107 #endif
108 bootloader_sha256_finish(sig_block_sha, key_digest);
109
110 // Check we can verify the image using this signature and this key
111 uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
112 #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
113 bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
114 #elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
115 bool verified = ets_ecdsa_verify(&block->ecdsa.key.point[0], block->ecdsa.signature, block->ecdsa.key.curve_id, image_digest, temp_verified_digest);
116 #endif
117
118 if (!verified) {
119 /* We don't expect this: the signature blocks before we enable secure boot should all be verifiable or invalid,
120 so this is a fatal error
121 */
122 ret = ESP_FAIL;
123 ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i);
124 break;
125 }
126 ESP_LOGD(TAG, "Signature block (%d) is verified", i);
127 /* Copy the key digest to the buffer provided by the caller */
128 memcpy((void *)public_key_digests->key_digests[i], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
129 public_key_digests->num_digests++;
130 }
131
132 if (ret == ESP_OK && public_key_digests->num_digests > 0) {
133 ESP_LOGI(TAG, "Digests successfully calculated, %d valid signatures (image offset 0x%x)",
134 public_key_digests->num_digests, flash_offset);
135 }
136
137 bootloader_munmap(signatures);
138 return ret;
139 }
140
check_and_generate_secure_boot_keys(void)141 esp_err_t check_and_generate_secure_boot_keys(void)
142 {
143 esp_err_t ret;
144 #ifdef CONFIG_IDF_TARGET_ESP32
145 esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_SECURE_BOOT);
146 if (coding_scheme != EFUSE_CODING_SCHEME_NONE) {
147 ESP_LOGE(TAG, "No coding schemes are supported in secure boot v2.(Detected scheme: 0x%x)", coding_scheme);
148 return ESP_ERR_NOT_SUPPORTED;
149 }
150 #endif // CONFIG_IDF_TARGET_ESP32
151
152 esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
153 #if SECURE_BOOT_NUM_BLOCKS == 1
154 ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
155 #else
156 ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
157 ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
158 ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
159 #endif
160 };
161
162 /* Verify the bootloader */
163 esp_image_metadata_t bootloader_data = { 0 };
164 ret = esp_image_verify_bootloader_data(&bootloader_data);
165 if (ret != ESP_OK) {
166 ESP_LOGE(TAG, "bootloader image appears invalid! error %d", ret);
167 return ret;
168 }
169
170 /* Initialize all efuse block entries to invalid (max) value */
171 esp_efuse_block_t blocks[SECURE_BOOT_NUM_BLOCKS] = {[0 ... SECURE_BOOT_NUM_BLOCKS-1] = EFUSE_BLK_KEY_MAX};
172 /* Check if secure boot digests are present */
173 bool has_secure_boot_digest = false;
174 for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
175 bool tmp_has_key = esp_efuse_find_purpose(secure_boot_key_purpose[i], &blocks[i]);
176 if (tmp_has_key) { // For ESP32: esp_efuse_find_purpose() always returns True, need to check whether the key block is used or not.
177 tmp_has_key &= !esp_efuse_key_block_unused(blocks[i]);
178 }
179 has_secure_boot_digest |= tmp_has_key;
180 }
181
182 esp_image_sig_public_key_digests_t boot_key_digests = {0};
183 ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating..");
184
185 if (!has_secure_boot_digest) {
186 /* Generate the bootloader public key digests */
187 ret = s_calculate_image_public_key_digests(bootloader_data.start_addr, bootloader_data.image_len - SIG_BLOCK_PADDING, &boot_key_digests);
188 if (ret != ESP_OK) {
189 ESP_LOGE(TAG, "Bootloader signature block is invalid");
190 return ret;
191 }
192
193 if (boot_key_digests.num_digests == 0) {
194 ESP_LOGE(TAG, "No valid bootloader signature blocks found.");
195 return ESP_FAIL;
196 }
197 ESP_LOGI(TAG, "%d signature block(s) found appended to the bootloader.", boot_key_digests.num_digests);
198
199 ESP_LOGI(TAG, "Burning public key hash to eFuse");
200 ret = esp_efuse_write_keys(secure_boot_key_purpose, boot_key_digests.key_digests, boot_key_digests.num_digests);
201 if (ret != ESP_OK) {
202 if (ret == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
203 ESP_LOGE(TAG, "Bootloader signatures(%d) more than available key slots.", boot_key_digests.num_digests);
204 } else {
205 ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", ret);
206 }
207 return ret;
208 }
209 } else {
210 for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
211 /* Check if corresponding digest slot is used or not */
212 if (blocks[i] == EFUSE_BLK_KEY_MAX) {
213 ESP_LOGD(TAG, "SECURE_BOOT_DIGEST%d slot is not used", i);
214 continue;
215 }
216
217 #if SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
218 if (esp_efuse_get_digest_revoke(i)) {
219 continue;
220 }
221 #endif
222 #ifndef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
223 if (esp_efuse_get_key_dis_read(blocks[i])) {
224 ESP_LOGE(TAG, "Key digest (BLK%d) read protected, aborting...", blocks[i]);
225 return ESP_FAIL;
226 }
227 #endif
228 if (esp_efuse_block_is_empty(blocks[i])) {
229 ESP_LOGE(TAG, "%d eFuse block is empty, aborting...", blocks[i]);
230 return ESP_FAIL;
231 }
232 esp_efuse_set_key_dis_write(blocks[i]);
233 #ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
234 size_t offset = 128;
235 #else
236 size_t offset = 0;
237 #endif
238 ret = esp_efuse_read_block(blocks[i], boot_key_digests.key_digests[boot_key_digests.num_digests], offset,
239 ESP_SECURE_BOOT_KEY_DIGEST_LEN * 8);
240 if (ret) {
241 ESP_LOGE(TAG, "Error during reading %d eFuse block (err=0x%x)", blocks[i], ret);
242 return ret;
243 }
244 boot_key_digests.num_digests++;
245 }
246 if (boot_key_digests.num_digests == 0) {
247 ESP_LOGE(TAG, "No valid pre-loaded public key digest in eFuse");
248 return ESP_FAIL;
249 }
250 ESP_LOGW(TAG, "Using pre-loaded public key digest in eFuse");
251 }
252
253 #if SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
254 /* Revoke the empty signature blocks */
255 if (boot_key_digests.num_digests < SECURE_BOOT_NUM_BLOCKS) {
256 /* The revocation index can be 0, 1, 2. Bootloader count can be 1,2,3. */
257 for (unsigned i = boot_key_digests.num_digests; i < SECURE_BOOT_NUM_BLOCKS; i++) {
258 ESP_LOGI(TAG, "Revoking empty key digest slot (%d)...", i);
259 esp_efuse_set_digest_revoke(i);
260 }
261 }
262 #endif // SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
263 return ESP_OK;
264 }
265
266 #endif // CONFIG_SECURE_BOOT_V2_ENABLED
267