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