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