Generic questions about secure boot & flash enc

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Generic questions about secure boot & flash enc

Postby WiFive » Fri Mar 29, 2019 12:15 am

ESP_Angus wrote:
Thu Mar 28, 2019 11:05 pm
Hi urbanze,

You don't need a new chip.
urbanze wrote:
Thu Mar 28, 2019 11:58 am

Code: Select all

E (112) flash_encrypt: Cannot re-encrypt data (FLASH_CRYPT_CNT 0xff write disabled 0
This is a bug in the IDF bootloader (it thinks FLASH_CRYPT_CNT 0xFF means encryption is disabled not enabled, so it's trying to encrypt again). Will fix ASAP.
Oops I guess both me and bootloader forgot top bit is ignored in FLASH_CRYPT_CNT so both 0xff and 0x7f means encryption is permanently enabled.

User avatar
urbanze
Posts: 295
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: Generic questions about secure boot & flash enc

Postby urbanze » Fri Mar 29, 2019 1:43 am

Since it is safe to play Flash Crypto with pre-generated key, I will continue abusing the code upload and my adventures. Waiting for this bugfix, thanks for the help guys.

One last question at this moment (besides the previous ones that I will copy)

2. To upload new bootloader, I need to upload it crypted or decrypted?
3. To upload new ota_data_initial, I need to upload it crypted or decrypted?
4. To upload new partitions, I need to upload it crypted or decrypted?

5.I said in one post later:
The upload of the binary to the server will no longer be the RAW .bin file, but rather the encrypted file with the same key
but since flash crypto with pre key need to be uploaded with .bin crypted, I can upload this crypted to server or need to recrypt again?!

User avatar
urbanze
Posts: 295
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: Generic questions about secure boot & flash enc

Postby urbanze » Fri Mar 29, 2019 4:55 pm

urbanze wrote:
Fri Mar 29, 2019 1:43 am
Since it is safe to play Flash Crypto with pre-generated key, I will continue abusing the code upload and my adventures. Waiting for this bugfix, thanks for the help guys.

One last question at this moment (besides the previous ones that I will copy)

2. To upload new bootloader, I need to upload it crypted or decrypted?
3. To upload new ota_data_initial, I need to upload it crypted or decrypted?
4. To upload new partitions, I need to upload it crypted or decrypted?

5.I said in one post later:
The upload of the binary to the server will no longer be the RAW .bin file, but rather the encrypted file with the same key
but since flash crypto with pre key need to be uploaded with .bin crypted, I can upload this crypted to server or need to recrypt again?!
2. crypted.
3. crypted.
4. crypted.
Sending anyone decrypted will fail and eFuse..._CTN still in past value (good notice hehe)
Sending anyone crypted will work and eFuse..._CTN still in past value (expected)

5. Apparently, no need to crypt again to decrypt in code, just send this .bin crypted by "compiler" to server.

Can anyone tell me how --force-write-always works? Unintentionally I ran make flash before burning the key :lol: :lol: :cry:

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Generic questions about secure boot & flash enc

Postby ESP_Angus » Sun Mar 31, 2019 10:53 pm

Hi urbanze,
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
2. crypted.
3. crypted.
4. crypted.
Sending anyone decrypted will fail and eFuse..._CTN still in past value (good notice hehe)
Sending anyone crypted will work and eFuse..._CTN still in past value (expected)
That's right, any time FLASH_CRYPT_CNT has an odd number of bits set (or 0xFF) -> all these things have to be encrypted.

Any time FLASH_CRYPT_CNT has an even number of bits set (but not 0xFF) -> all of these things have to be plaintext.

Otherwise, the ESP32 is unable to read the data from flash.
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
5. Apparently, no need to crypt again to decrypt in code, just send this .bin crypted by "compiler" to server.
Kind of. There are two things to consider here:

1. The OTA app_update framework assumes that the binary data you give it is plaintext, and it uses the esp_partition APIs which will automatically encrypt anything written to a partition with flash encryption enabled. This means it will double-encrypt the OTA if it's already flash encrypted data, and you won't be able to boot. If you write your own routines to write to flash, you can write the flash encrypted data as-is.

2. Distributing pre-encrypted binaries on the server means either (a) you use the same flash key on all devices, or (b) you have to store a different binary for each ESP32, and keep a database of which ESP32 has which key. We don't recommend (a), because a compromise of one flash key will compromise all your devices. If you're not concerned about this then you can do (a), though. Doing (b) is possible but complex, which is why we want to develop an alternative method for encrypting the OTA binary on the server.
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
Can anyone tell me how --force-write-always works? Unintentionally I ran make flash before burning the key :lol: :lol: :cry:
Normally, "espefuse.py burn_key" will fail in software if it looks like the efuse key (BLK1, BLK2 or BLK3) has already been burned, rather than try to burn it anyhow.

"--force-write-always" will cause espefuse.py to try and burn it anyhow. If the efuse is write protected, this will do nothing as the write will be blocked in hardware. If the efuse is not write protected, the result will be bitwise or: (Old Contents) | (New Contents), because efuse bits can only be burned 0->1 not the other way around.

If you accidentally booted an ESP32 with flash encryption enabled in the bootloader, no "insecure options", and no pre-burned key then it will have generated a random key, written it to efuse, and then read and write protected it. You can't change this key or access it. The only thing you can do to update this ESP32 is to follow the "serial flashing" process where you disable flash encryption and reflash it again. Flash encryption can be re-enalbed this way up to 3 times, total: https://docs.espressif.com/projects/esp ... l-flashing

(Note that if you disable flash encryption and don't re-enable it, you can keep using this ESP32 as normal.)

User avatar
urbanze
Posts: 295
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: Generic questions about secure boot & flash enc

Postby urbanze » Wed Jun 19, 2019 6:22 am

ESP_Angus wrote:
Sun Mar 31, 2019 10:53 pm
Hi urbanze,
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
2. crypted.
3. crypted.
4. crypted.
Sending anyone decrypted will fail and eFuse..._CTN still in past value (good notice hehe)
Sending anyone crypted will work and eFuse..._CTN still in past value (expected)
That's right, any time FLASH_CRYPT_CNT has an odd number of bits set (or 0xFF) -> all these things have to be encrypted.

Any time FLASH_CRYPT_CNT has an even number of bits set (but not 0xFF) -> all of these things have to be plaintext.

Otherwise, the ESP32 is unable to read the data from flash.
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
5. Apparently, no need to crypt again to decrypt in code, just send this .bin crypted by "compiler" to server.
Kind of. There are two things to consider here:

1. The OTA app_update framework assumes that the binary data you give it is plaintext, and it uses the esp_partition APIs which will automatically encrypt anything written to a partition with flash encryption enabled. This means it will double-encrypt the OTA if it's already flash encrypted data, and you won't be able to boot. If you write your own routines to write to flash, you can write the flash encrypted data as-is.

2. Distributing pre-encrypted binaries on the server means either (a) you use the same flash key on all devices, or (b) you have to store a different binary for each ESP32, and keep a database of which ESP32 has which key. We don't recommend (a), because a compromise of one flash key will compromise all your devices. If you're not concerned about this then you can do (a), though. Doing (b) is possible but complex, which is why we want to develop an alternative method for encrypting the OTA binary on the server.
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
Can anyone tell me how --force-write-always works? Unintentionally I ran make flash before burning the key :lol: :lol: :cry:
Normally, "espefuse.py burn_key" will fail in software if it looks like the efuse key (BLK1, BLK2 or BLK3) has already been burned, rather than try to burn it anyhow.

"--force-write-always" will cause espefuse.py to try and burn it anyhow. If the efuse is write protected, this will do nothing as the write will be blocked in hardware. If the efuse is not write protected, the result will be bitwise or: (Old Contents) | (New Contents), because efuse bits can only be burned 0->1 not the other way around.

If you accidentally booted an ESP32 with flash encryption enabled in the bootloader, no "insecure options", and no pre-burned key then it will have generated a random key, written it to efuse, and then read and write protected it. You can't change this key or access it. The only thing you can do to update this ESP32 is to follow the "serial flashing" process where you disable flash encryption and reflash it again. Flash encryption can be re-enalbed this way up to 3 times, total: https://docs.espressif.com/projects/esp ... l-flashing

(Note that if you disable flash encryption and don't re-enable it, you can keep using this ESP32 as normal.)
Can I disable OTA API to crypt .bin before flash write? With this, I can simple upload .bin crypted by compiler and OTA API just write without recrypt and free a lot of my time to write new functions to download from server, decrypt and etc.

If not default in API, this is complex to change in API? Or do my routine to decrypt is better/easy?

User avatar
urbanze
Posts: 295
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: Generic questions about secure boot & flash enc

Postby urbanze » Sun Aug 18, 2019 7:54 pm

ESP_Angus wrote:
Sun Mar 31, 2019 10:53 pm
Hi urbanze,
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
2. crypted.
3. crypted.
4. crypted.
Sending anyone decrypted will fail and eFuse..._CTN still in past value (good notice hehe)
Sending anyone crypted will work and eFuse..._CTN still in past value (expected)
That's right, any time FLASH_CRYPT_CNT has an odd number of bits set (or 0xFF) -> all these things have to be encrypted.

Any time FLASH_CRYPT_CNT has an even number of bits set (but not 0xFF) -> all of these things have to be plaintext.

Otherwise, the ESP32 is unable to read the data from flash.
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
5. Apparently, no need to crypt again to decrypt in code, just send this .bin crypted by "compiler" to server.
Kind of. There are two things to consider here:

1. The OTA app_update framework assumes that the binary data you give it is plaintext, and it uses the esp_partition APIs which will automatically encrypt anything written to a partition with flash encryption enabled. This means it will double-encrypt the OTA if it's already flash encrypted data, and you won't be able to boot. If you write your own routines to write to flash, you can write the flash encrypted data as-is.

2. Distributing pre-encrypted binaries on the server means either (a) you use the same flash key on all devices, or (b) you have to store a different binary for each ESP32, and keep a database of which ESP32 has which key. We don't recommend (a), because a compromise of one flash key will compromise all your devices. If you're not concerned about this then you can do (a), though. Doing (b) is possible but complex, which is why we want to develop an alternative method for encrypting the OTA binary on the server.
urbanze wrote:
Fri Mar 29, 2019 4:55 pm
Can anyone tell me how --force-write-always works? Unintentionally I ran make flash before burning the key :lol: :lol: :cry:
Normally, "espefuse.py burn_key" will fail in software if it looks like the efuse key (BLK1, BLK2 or BLK3) has already been burned, rather than try to burn it anyhow.

"--force-write-always" will cause espefuse.py to try and burn it anyhow. If the efuse is write protected, this will do nothing as the write will be blocked in hardware. If the efuse is not write protected, the result will be bitwise or: (Old Contents) | (New Contents), because efuse bits can only be burned 0->1 not the other way around.

If you accidentally booted an ESP32 with flash encryption enabled in the bootloader, no "insecure options", and no pre-burned key then it will have generated a random key, written it to efuse, and then read and write protected it. You can't change this key or access it. The only thing you can do to update this ESP32 is to follow the "serial flashing" process where you disable flash encryption and reflash it again. Flash encryption can be re-enalbed this way up to 3 times, total: https://docs.espressif.com/projects/esp ... l-flashing

(Note that if you disable flash encryption and don't re-enable it, you can keep using this ESP32 as normal.)
With pre-generated key and protected FLASH_CRYPT_CNT (in odd), esp32 will accept only crypted binaries, then, why Espressif tells to enable secure boot? What is the insecure that option returns? With _CTN protected, secure boot is really necessary?

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Generic questions about secure boot & flash enc

Postby WiFive » Sun Aug 18, 2019 11:20 pm

In general encryption provides more protection than secure boot. Is secure boot useless? The main reason for secure boot is to signature check the bootloader because otherwise it only has simple checksum. So if you start flipping bits, even though it is encrypted you might be able to get a corrupt bootloader to run. But you can bypass secure boot with timing attack so... not sure.

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Generic questions about secure boot & flash enc

Postby ESP_Angus » Mon Aug 19, 2019 12:08 am

urbanze wrote:
Sun Aug 18, 2019 7:54 pm
With pre-generated key and protected FLASH_CRYPT_CNT (in odd), esp32 will accept only crypted binaries, then, why Espressif tells to enable secure boot? What is the insecure that option returns? With _CTN protected, secure boot is really necessary?
As WiFive says, it may be possible for an attacker to selectively corrupt the flash. Also, if an attacker can get arbitrary code execution on the device somehow (for example: impersonate an OTA update server, or exploit a software buffer overflow bug) then secure boot prevents this attack from being persisted in the flash.

There is also an aspect of "defence in depth" here, if in the future a problem surfaces in one of the two then it's better to have both enabled.

Depending on your device's threat model (ie what kind of attacks you're concerned about, what kind of security impact you're concerned about), then you may want to disregard this advice. Up to you.

Who is online

Users browsing this forum: No registered users and 120 guests