From 812a92c703c744771a8b68f0b28b2f1a4d9e1b67 Mon Sep 17 00:00:00 2001 From: Sachin Parekh Date: Fri, 22 Oct 2021 11:53:40 +0530 Subject: [PATCH 1/2] secure_boot: Added Kconfig option for aggressive key revoke Applicable to S2, C3, and S3 --- components/bootloader/Kconfig.projbuild | 16 ++++++++++++++++ docs/en/security/secure-boot-v2.rst | 16 +++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 42e0b5ebe6..e6f0e99a7a 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -593,6 +593,22 @@ menu "Security features" Refer to the Secure Boot section of the ESP-IDF Programmer's Guide for this version before enabling. + config SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE + bool "Enable Aggressive key revoke strategy" + depends on SECURE_BOOT && (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3) + default N + help + If this option is set, ROM bootloader will revoke the public key digest burned in efuse block + if it fails to verify the signature of software bootloader with it. + Revocation of keys does not happen when enabling secure boot. Once secure boot is enabled, + key revocation checks will be done on subsequent boot-up, while verifying the software bootloader + + This feature provides a strong resistance against physical attacks on the device. + + NOTE: Once a digest slot is revoked, it can never be used again to verify an image + This can lead to permanent bricking of the device, in case all keys are revoked + because of signature verification failure. + choice SECURE_BOOTLOADER_KEY_ENCODING bool "Hardware Key Encoding" depends on SECURE_BOOTLOADER_REFLASHABLE diff --git a/docs/en/security/secure-boot-v2.rst b/docs/en/security/secure-boot-v2.rst index 0ee7d8c2ba..0a2bffc3c5 100644 --- a/docs/en/security/secure-boot-v2.rst +++ b/docs/en/security/secure-boot-v2.rst @@ -298,7 +298,10 @@ Secure Boot Best Practices * Applications should be signed with only one key at a time, to minimise the exposure of unused private keys. * The bootloader can be signed with multiple keys from the factory. - Assuming a trusted private key (N-1) has been compromised, to update to new keypair (N). + Conservative approach: + ~~~~~~~~~~~~~~~~~~~~~~ + + Assuming a trusted private key (N-1) has been compromised, to update to new key pair (N). 1. Server sends an OTA update with an application signed with the new private key (#N). 2. The new OTA update is written to an unused OTA app partition. @@ -310,6 +313,17 @@ Secure Boot Best Practices * A similiar approach can also be used to physically reflash with a new key. For physical reflashing, the bootloader content can also be changed at the same time. + Aggressive approach: + ~~~~~~~~~~~~~~~~~~~~ + + ROM code has an additional feature of revoking a public key digest if the signature verification fails. + + To enable this feature, you need to burn SECURE_BOOT_AGGRESSIVE_REVOKE efuse or enable :ref:`CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE` + + Key revocation is not applicable unless secure boot is successfully enabled. Also, a key is not revoked in case of invalid signature block or invalid image digest, it is only revoked in case the signature verification fails, i.e. revoke key only if failure in step 4 of :ref:`verify_signature-block` + + Once a key is revoked, it can never be used for verfying a signature of an image. This feature provides strong resistance against physical attacks on the device. However, this could also brick the device permanently if all the keys are revoked because of signature verification failure. + .. _secure-boot-v2-technical-details: Technical Details From 017f7a241aa5baacaa39014b3f745c6c49151c5f Mon Sep 17 00:00:00 2001 From: Sachin Parekh Date: Fri, 22 Oct 2021 12:11:15 +0530 Subject: [PATCH 2/2] secure_boot: Do not allow key revocation in bootloader --- .../src/secure_boot_v2/secure_boot_signatures_bootloader.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c index 09e167b057..bb4e77bbf1 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c @@ -155,10 +155,13 @@ esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signa #if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS == 1 int sb_result = ets_secure_boot_verify_signature(sig_block, image_digest, trusted.key_digests[0], verified_digest); #else - ets_secure_boot_key_digests_t trusted_key_digests; + ets_secure_boot_key_digests_t trusted_key_digests = {0}; for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) { trusted_key_digests.key_digests[i] = &trusted.key_digests[i]; } + // Key revocation happens in ROM bootloader. + // Do NOT allow key revocation while verifying application + trusted_key_digests.allow_key_revoke = false; int sb_result = ets_secure_boot_verify_signature(sig_block, image_digest, &trusted_key_digests, verified_digest); #endif if (sb_result != SB_SUCCESS) {