Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TW#18644] Secure Boot enabled before checking partition table signature #1641

Closed
catalinio opened this issue Feb 19, 2018 · 9 comments
Closed
Assignees

Comments

@catalinio
Copy link

Hi,
In the SecureBoot description there is this paragraph:

NOTE Secure boot won’t be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured.

After I've checked the code from bootloader_start.c, it seems that if I flash: bootloader(with Secure Boot enabled), partitions.bin and application.bin; then the SecureBoot efuse (ABS_DONE_0) is set, even if partitions and application are not signed (or wrong SHA digest).

Basically, what happens:

  1. Bootloader started, Secure Boot efuse is not written (yet) so partition and application are not checked
  2. Secure Boot is enabled (Flash Encryption is enabled), and application is loaded successful
  3. after first reset, the partition and application are checked, and fail, so bootloader is stuck

Solution here, would be to re-sign partition and application and re-flash them on serial.

More tragic, is that if Flash Encryption is enabled, all the partitions (bootloader, parition table, factory app) are encrypted (with the secret efuse key). I guess, the esp32 chip is bricked; can't even use OTA for updating.

@negativekelvin
Copy link
Contributor

negativekelvin commented Feb 21, 2018

It looks like partition table is not checked

#ifdef CONFIG_SECURE_BOOT_ENABLED
if(esp_secure_boot_enabled()) {
ESP_LOGI(TAG, "Verifying partition table signature...");
err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN);

But app image is checked

#ifdef CONFIG_SECURE_BOOT_ENABLED
if (1) {

#ifdef CONFIG_SECURE_BOOT_ENABLED
// secure boot images have a signature appended
err = verify_secure_boot_signature(sha_handle, data);

@projectgus

@projectgus projectgus self-assigned this Feb 21, 2018
@FayeY FayeY changed the title Secure Boot enabled before checking valid app image [TW#18644] Secure Boot enabled before checking valid app image Feb 23, 2018
@projectgus
Copy link
Contributor

Hi @catalinio ,

Sorry for the delay in getting back to you. I believe @negativekelvin is right here. The app signature is checked on the first boot before secure boot is enabled, but the partition table signature is not checked until the second boot after secure boot is enabled (only basic partition table integrity is checked on the first boot). If someone accidentally flashes an unsigned but otherwise valid partition table and enables flash encryption, they can be left with an unbootable ESP32.

As it happens, we've recently discussed removing the partition table signature check entirely to speed up boot times when secure boot is on. Any hypothetical attacker who can rewrite the partition table is able to make arbitrary flash writes, so they can always rewrite existing partition contents instead.[*]. So we will probably solve this by removing the partition table signature check entirely (improving the boot time when secure boot is enabled).

[*] Previously there may have been a hypothetical weakness if an attacker could write to but not erase arbitrary flash. They could hypothetically extend an unsigned partition table rather than rewriting it. However the new MD5 appended to the partition table fixes this as it's impossible to repurpose that entry without erasing first.

@projectgus projectgus changed the title [TW#18644] Secure Boot enabled before checking valid app image [TW#18644] Secure Boot enabled before checking partition table signature Mar 15, 2018
@negativekelvin
Copy link
Contributor

@projectgus while you are in there, what about write protect flash_crypt_cnt automatically when secure boot and non-reflashable bootloader selected?

@projectgus
Copy link
Contributor

@negativekelvin That seems reasonable. FWIW I don't think there's a situation where this can lead to permanent problems, though (even if it's accidentally burned again to disable encryption, you can always burn it one more time to get encryption back on.)

@negativekelvin
Copy link
Contributor

Unless it is burned to 0xff. Probably not a big concern but someone could permanently disable a device that way.

@projectgus
Copy link
Contributor

Fair enough, will change this. Although please note that if a hypothetical malicious attacker is in a position to burn arbitrary efuses, they have lot of ways to permanently disable the device (via efuses and via other means.)

@negativekelvin
Copy link
Contributor

negativekelvin commented Mar 15, 2018

That is true, other efuses would need to have write protect set but that could be done before first boot. Yes someone could still corrupt the flash chip, but at least we can take all reasonable measures.

What is EFUSE_ABS_DONE_1 for and what do bits 4&11 of efuse_wr_disable do?

@negativekelvin
Copy link
Contributor

@projectgus these changes didn't make it into bootloader refactor?

@projectgus
Copy link
Contributor

@negativekelvin No, those were separate changes. But we haven't forgotten about this.

@igrr igrr closed this as completed in fb439e4 Jul 28, 2018
igrr pushed a commit that referenced this issue Jul 30, 2018
Partition Tables are still signed for backwards compatibility, but signature is no longer checked as
part of bootloader.

Closes #1641
catalinio pushed a commit to catalinio/pycom-esp-idf that referenced this issue Jun 28, 2019
Partition Tables are still signed for backwards compatibility, but signature is no longer checked as
part of bootloader.

Closes espressif/esp-idf#1641
catalinio pushed a commit to catalinio/pycom-esp-idf that referenced this issue Jun 28, 2019
Partition Tables are still signed for backwards compatibility, but signature is no longer checked as
part of bootloader.

Closes espressif/esp-idf#1641
0xFEEDC0DE64 pushed a commit to 0xFEEDC0DE64/esp-idf that referenced this issue May 5, 2021
…1641)

EEPROM.h uses data types which are declared through Arduino.h but that file does not contain an #include directive for Arduino.h. This does not cause any problems when the EEPROM library is #included from a .ino file because the Arduino IDE automatically adds an #include directive for Arduino.h but this is not the case for .cpp files. If a .cpp file has an #include directive for EEPROM.h that does not follow an #include directive for Arduino.h then compilation fails:

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:91:5: error: 'float_t' does not name a type

     float_t readFloat(int address);

     ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:92:5: error: 'double_t' does not name a type

     double_t readDouble(int address);

     ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:95:5: error: 'String' does not name a type

     String readString(int address);

     ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:110:36: error: 'float_t' has not been declared

     size_t writeFloat(int address, float_t value);

                                    ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:111:37: error: 'double_t' has not been declared

     size_t writeDouble(int address, double_t value);

                                     ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:114:37: error: 'String' has not been declared

     size_t writeString(int address, String value);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants