From 073ba0a608ae2b79d461a94545fbc2b0709530db Mon Sep 17 00:00:00 2001 From: Supreet Deshpande Date: Tue, 25 Feb 2020 01:24:16 +0530 Subject: [PATCH] feat/secure_boot_v2: Adding docs for secure boot v2 ESP32-ECO3 --- docs/conf_common.py | 2 + docs/en/api-guides/bootloader.rst | 2 +- docs/en/api-guides/index.rst | 3 +- docs/en/api-guides/partition-tables.rst | 2 +- .../api-reference/system/app_image_format.rst | 2 +- .../en/api-reference/system/esp_https_ota.rst | 8 +- docs/en/api-reference/system/ota.rst | 10 +- docs/en/security/flash-encryption.rst | 32 ++- .../{secure-boot.rst => secure-boot-v1.rst} | 7 +- docs/en/security/secure-boot-v2.rst | 239 ++++++++++++++++++ docs/page_redirects.txt | 5 +- docs/zh_CN/api-guides/index.rst | 3 +- docs/zh_CN/api-guides/partition-tables.rst | 6 +- docs/zh_CN/security/flash-encryption.rst | 32 ++- docs/zh_CN/security/secure-boot-v1.rst | 1 + docs/zh_CN/security/secure-boot-v2.rst | 1 + docs/zh_CN/security/secure-boot.rst | 1 - 17 files changed, 323 insertions(+), 33 deletions(-) rename docs/en/security/{secure-boot.rst => secure-boot-v1.rst} (98%) create mode 100644 docs/en/security/secure-boot-v2.rst create mode 100644 docs/zh_CN/security/secure-boot-v1.rst create mode 100644 docs/zh_CN/security/secure-boot-v2.rst delete mode 100644 docs/zh_CN/security/secure-boot.rst diff --git a/docs/conf_common.py b/docs/conf_common.py index bc9fc63f5..6e6848d4f 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -147,6 +147,8 @@ def update_exclude_patterns(tags): 'api-reference/protocols/esp_serial_slave_link.rst', 'api-reference/system/ipc.rst', 'get-started-legacy/**', + 'security/secure-boot-v1.rst', + 'security/secure-boot-v2.rst', 'gnu-make-legacy.rst', 'hw-reference/esp32/**', ]: diff --git a/docs/en/api-guides/bootloader.rst b/docs/en/api-guides/bootloader.rst index a849eb695..6f3924794 100644 --- a/docs/en/api-guides/bootloader.rst +++ b/docs/en/api-guides/bootloader.rst @@ -57,7 +57,7 @@ After the GPIO input is deactivated and the device reboots, the normally configu Fast boot from Deep Sleep ------------------------- -The bootloader has the :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` option which allows to reduce the wake-up time (useful to reduce consumption). This option is available when the :ref:`CONFIG_SECURE_BOOT_ENABLED` option is disabled. Reduction of time is achieved due to the lack of image verification. During the first boot, the bootloader stores the address of the application being launched in the RTC FAST memory. And during the awakening, this address is used for booting without any checks, thus fast loading is achieved. +The bootloader has the :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` option which allows to reduce the wake-up time (useful to reduce consumption). This option is available when the :ref:`CONFIG_SECURE_BOOT` option is disabled. Reduction of time is achieved due to the lack of image verification. During the first boot, the bootloader stores the address of the application being launched in the RTC FAST memory. And during the awakening, this address is used for booting without any checks, thus fast loading is achieved. Customer bootloader --------------------- diff --git a/docs/en/api-guides/index.rst b/docs/en/api-guides/index.rst index c978e5fca..4b11122ac 100644 --- a/docs/en/api-guides/index.rst +++ b/docs/en/api-guides/index.rst @@ -28,7 +28,8 @@ API Guides Partition Tables :esp32: RF Calibration ROM debug console - Secure Boot <../security/secure-boot> + :esp32: Secure Boot <../security/secure-boot-v1> + :esp32: Secure Boot V2 <../security/secure-boot-v2> Thread Local Storage Tools ULP Coprocessor diff --git a/docs/en/api-guides/partition-tables.rst b/docs/en/api-guides/partition-tables.rst index c0cdea82a..e1730c0d3 100644 --- a/docs/en/api-guides/partition-tables.rst +++ b/docs/en/api-guides/partition-tables.rst @@ -265,4 +265,4 @@ More information can be obtained by specifying `--help` as argument: parttool.py [subcommand] --help -.. _secure boot: security/secure-boot.rst +.. _secure boot: security/secure-boot-v1.rst diff --git a/docs/en/api-reference/system/app_image_format.rst b/docs/en/api-reference/system/app_image_format.rst index a2e61ea45..80ab5e922 100644 --- a/docs/en/api-reference/system/app_image_format.rst +++ b/docs/en/api-reference/system/app_image_format.rst @@ -62,7 +62,7 @@ For more details on the type of memory segments and their address ranges, see th 3. The image has a single checksum byte after the last segment. This byte is written on a sixteen byte padded boundary, so the application image might need padding. 4. If the ``hash_appended`` field from :cpp:type:`esp_image_header_t` is set then a SHA256 checksum will be appended. The value of SHA256 is calculated on the range from first byte and up to this field. The length of this field is 32 bytes. -5. If the options :ref:`CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT` or :ref:`CONFIG_SECURE_BOOT_ENABLED` are enabled then the application image will have additional 68 bytes for an ECDSA signature, which includes: +5. If the options :ref:`CONFIG_SECURE_SIGNED_APPS_SCHEME` is set to ECDSA then the application image will have additional 68 bytes for an ECDSA signature, which includes: * version word (4 bytes), * signature data (64 bytes). diff --git a/docs/en/api-reference/system/esp_https_ota.rst b/docs/en/api-reference/system/esp_https_ota.rst index f490b057a..ccf18e37e 100644 --- a/docs/en/api-reference/system/esp_https_ota.rst +++ b/docs/en/api-reference/system/esp_https_ota.rst @@ -29,10 +29,12 @@ Application Example return ESP_OK; } -Signature Verification ----------------------- +.. only:: esp32 -For additional security, signature of OTA firmware images can be verified. For that, refer :ref:`secure-ota-updates` + Signature Verification + ---------------------- + + For additional security, signature of OTA firmware images can be verified. For that, refer :ref:`secure-ota-updates` API Reference ------------- diff --git a/docs/en/api-reference/system/ota.rst b/docs/en/api-reference/system/ota.rst index 110c1dabe..e5c397c2e 100644 --- a/docs/en/api-reference/system/ota.rst +++ b/docs/en/api-reference/system/ota.rst @@ -194,14 +194,16 @@ Restrictions: - In ESP32 it is stored in efuse ``EFUSE_BLK3_RDATA4_REG``. (when a eFuse bit is programmed to 1, it can never be reverted to 0). The number of bits set in this register is the ``security_version`` from app. -.. _secure-ota-updates: +.. only:: esp32 -Secure OTA Updates Without Secure boot --------------------------------------- + .. _secure-ota-updates: -The verification of signed OTA updates can be performed even without enabling hardware secure boot. For doing so, refer :ref:`signed-app-verify` + Secure OTA Updates Without Secure boot + -------------------------------------- + The verification of signed OTA updates can be performed even without enabling hardware secure boot. For doing so, refer :ref:`signed-app-verify` + OTA Tool (otatool.py) --------------------- diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index e156a6e67..72604c334 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -25,7 +25,9 @@ With flash encryption enabled, following kinds of flash data are encrypted by de - Secure boot bootloader digest (if secure boot is enabled) - Any partition marked with the "encrypted" flag in the partition table -Flash encryption is separate from the :doc:`Secure Boot ` feature, and you can use flash encryption without enabling secure boot. However, for a secure environment both should be used simultaneously. +.. only:: esp32 + + Flash encryption is separate from the :doc:`Secure Boot ` feature, and you can use flash encryption without enabling secure boot. However, for a secure environment both should be used simultaneously. .. important:: For production use, flash encryption should be enabled in the "Release" mode only. @@ -130,7 +132,9 @@ As mentioned above :ref:`flash_enc_development_mode` allows user to download as - Select appropriate Bootloader log verbosity under Bootloader config. -- Update to the partition table offset may be required since after enabling flash encryption the size of bootloader is increased. See :ref:`secure-boot-bootloader-size` +.. only:: esp32 + + - Update to the partition table offset may be required since after enabling flash encryption the size of bootloader is increased. See :ref:`secure-boot-bootloader-size` - Save the configuration and exit. @@ -326,7 +330,9 @@ It is possible to pregenerate the flash encryption key on the host computer and - Select appropriate Bootloader log verbosity under Bootloader config. -- Update to the partition table offset may be required since after enabling flash encryption the size of bootloader is increased. See :ref:`secure-boot-bootloader-size` +.. only:: esp32 + + - Update to the partition table offset may be required since after enabling flash encryption the size of bootloader is increased. See :ref:`secure-boot-bootloader-size` - Save the configuration and exit. @@ -364,7 +370,9 @@ In Release mode UART bootloader can not perform flash encryption operations and - Select appropriate Bootloader log verbosity under Bootloader config. -- Update to the partition table offset may be required since after enabling flash encryption the size of bootloader is increased. See :ref:`secure-boot-bootloader-size` +.. only:: esp32 + + - Update to the partition table offset may be required since after enabling flash encryption the size of bootloader is increased. See :ref:`secure-boot-bootloader-size` - Save the configuration and exit. @@ -487,7 +495,9 @@ Key Points About Flash Encryption - If secure boot is enabled, reflashing the bootloader of an encrypted device requires a "Reflashable" secure boot digest (see :ref:`flash-encryption-and-secure-boot`). -.. note:: The bootloader app binary ``bootloader.bin`` may become too large when both secure boot and flash encryption are enabled. See :ref:`secure-boot-bootloader-size`. +.. only:: esp32 + + .. note:: The bootloader app binary ``bootloader.bin`` may become too large when both secure boot and flash encryption are enabled. See :ref:`secure-boot-bootloader-size`. .. important:: Do not interrupt power to the {IDF_TARGET_NAME} while the first boot encryption pass is running. If power is interrupted, the flash contents will be corrupted and require flashing with unencrypted data again. A reflash like this will not count towards the flashing limit. @@ -587,7 +597,9 @@ Flash encryption prevents plaintext readout of the encrypted flash, to protect f - For the same reason, an attacker can always tell when a pair of adjacent 16 byte blocks (32 byte aligned) contain two identical 16 byte sequences. Keep this in mind if storing sensitive data on the flash, design your flash storage so this doesn't happen (using a counter byte or some other non-identical value every 16 bytes is sufficient). :ref:`NVS Encryption ` deals with this and is suitable for many uses. -- Flash encryption alone may not prevent an attacker from modifying the firmware of the device. To prevent unauthorised firmware from running on the device, use flash encryption in combination with :doc:`Secure Boot `. +.. only:: esp32 + + - Flash encryption alone may not prevent an attacker from modifying the firmware of the device. To prevent unauthorised firmware from running on the device, use flash encryption in combination with :doc:`Secure Boot `. .. _flash-encryption-and-secure-boot: @@ -597,8 +609,12 @@ Flash Encryption and Secure Boot It is recommended to use flash encryption and secure boot together. However, if Secure Boot is enabled then additional restrictions apply to reflashing the device: - :ref:`updating-encrypted-flash-ota` are not restricted (provided the new app is signed correctly with the Secure Boot signing key). -- :ref:`Plaintext serial flash updates ` are only possible if the :ref:`Reflashable ` Secure Boot mode is selected and a Secure Boot key was pre-generated and burned to the {IDF_TARGET_NAME} (refer to :ref:`Secure Boot ` docs.). In this configuration, ``idf.py bootloader`` will produce a pre-digested bootloader and secure boot digest file for flashing at offset 0x0. When following the plaintext serial reflashing steps it is necessary to re-flash this file before flashing other plaintext data. -- :ref:`Reflashing via Pregenerated Flash Encryption Key ` is still possible, provided the bootloader is not reflashed. Reflashing the bootloader requires the same :ref:`Reflashable ` option to be enabled in the Secure Boot config. + +.. only:: esp32 + + - :ref:`Plaintext serial flash updates ` are only possible if the :ref:`Reflashable ` Secure Boot mode is selected and a Secure Boot key was pre-generated and burned to the {IDF_TARGET_NAME} (refer to :ref:`Secure Boot ` docs.). In this configuration, ``idf.py bootloader`` will produce a pre-digested bootloader and secure boot digest file for flashing at offset 0x0. When following the plaintext serial reflashing steps it is necessary to re-flash this file before flashing other plaintext data. + + - :ref:`Reflashing via Pregenerated Flash Encryption Key ` is still possible, provided the bootloader is not reflashed. Reflashing the bootloader requires the same :ref:`Reflashable ` option to be enabled in the Secure Boot config. .. _flash-encryption-advanced-features: diff --git a/docs/en/security/secure-boot.rst b/docs/en/security/secure-boot-v1.rst similarity index 98% rename from docs/en/security/secure-boot.rst rename to docs/en/security/secure-boot-v1.rst index e13b285a3..e583fe442 100644 --- a/docs/en/security/secure-boot.rst +++ b/docs/en/security/secure-boot-v1.rst @@ -1,6 +1,11 @@ Secure Boot =========== +.. important:: + + All references in this document are related to Secure Boot V1 (The AES based Secure Boot Scheme). ESP32 Revision 3 onwards, the preferred secure boot scheme is :doc:`Secure Boot V2 `. + Please refer to Secure Boot V2 document for ESP32 Revision 3 or ESP32S2. + Secure Boot is a feature for ensuring only your code can run on the chip. Data loaded from flash is verified on each reset. Secure Boot is separate from the :doc:`Flash Encryption ` feature, and you can use secure boot without encrypting the flash contents. However, for a secure environment both should be used simultaneously. See :ref:`secure-boot-and-flash-encr` for more details. @@ -133,7 +138,7 @@ In the esp-idf build process, this 256-bit key file is derived from the ECDSA ap To enable a reflashable bootloader: -1. In the :ref:`project-configuration-menu`, select "Bootloader Config" -> :ref:`CONFIG_SECURE_BOOT_ENABLED` -> :ref:`CONFIG_SECURE_BOOTLOADER_MODE` -> Reflashable. +1. In the :ref:`project-configuration-menu`, select "Bootloader Config" -> :ref:`CONFIG_SECURE_BOOT` -> CONFIG_SECURE_BOOT_V1_ENABLED -> :ref:`CONFIG_SECURE_BOOTLOADER_MODE` -> Reflashable. 2. If necessary, set the :ref:`CONFIG_SECURE_BOOTLOADER_KEY_ENCODING` based on the coding scheme used by the device. The coding scheme is shown in the ``Features`` line when ``esptool.py`` connects to the chip, or in the ``espefuse.py summary`` output. diff --git a/docs/en/security/secure-boot-v2.rst b/docs/en/security/secure-boot-v2.rst new file mode 100644 index 000000000..da5c0da19 --- /dev/null +++ b/docs/en/security/secure-boot-v2.rst @@ -0,0 +1,239 @@ +Secure Boot V2 +============== + +.. important:: + + The references in this document are related to Secure Boot v2, the preferred scheme from ESP32-ECO3 onwards and in ESP32S2. (Refer to :doc:`Secure Boot ` for ESP32) + + Secure Boot V2 uses RSA based app and bootloader verification. This document can also be referred for signing apps with the RSA scheme without signing the bootloader. + +Background +---------- + +Secure Boot protects a device from running unsigned code (verification at time of load). A new RSA based secure boot +verification scheme (Secure Boot V2) has been introduced for ESP32S2 and ESP32 ECO3 onwards. + +- The software bootloader’s RSA-PSS signature is verified by the Mask ROM and it is executed post successful verification. +- The verified software bootloader verifies the RSA-PSS signature of the application image before it is executed. + +Advantages +---------- + +- The RSA public key is stored on the device. The corresponding RSA private key is kept secret on a server and is never accessed by the device. + +- Upto three public keys can store can be generated and stored in ESP32S2 during manufacturing. (ESP32 ECO3: only one key) + +- ESP32S2 also provides the facility to revoke individual public keys. + +- Same image format & signature verification is applied for applications & software bootloader. + +- No secrets are stored on the device. Therefore immune to passive side-channel attacks (timing or power analysis, etc.) + + +Secure Boot V2 Process +---------------------- + +This is an overview of the Secure Boot V2 Process, Step by step instructions are supplied under :ref:`secure-boot-v2-howto`. + +1. Secure Boot V2 verifies the signature blocks appended to the bootloader and application binaries. The signature block contains the image binary signed by a RSA-3072 private key and its corresponding public key. More details on the :ref:`signature-block-format`. + +2. On startup, ROM code checks the secure boot v2 bit in eFuse. + +3. If secure boot is enabled, ROM checks the SHA-256 of the public key in the signature block in the eFuse. + +4. The ROM code validates the public key embedded in the software bootloader's signature block by matching the SHA-256 of its public key to the SHA-256 in eFuse as per the earlier step. Boot process will be aborted if a valid hash of the public key isn’t found in the eFuse. + +5. The ROM code verifies the signature of the bootloader with the pre-validated public key with the RSA-PSS Scheme. In depth information on :ref:`verify_signature-block`. + +6. Software bootloader, reads the app partition and performs similar verification on the application. The application is verified on every boot up and OTA update. If selected OTA app partition fails verification, bootloader will fall back and look for another correctly signed partition. + +.. _signature-block-format: + +Signature Block Format +---------------------- + +The bootloader and application images are padded to the next 4096 byte boundary, thus the signature has a flash sector of its own. The signature is calculated over all bytes in the image including the padding bytes. + +Each signature block contains the following: + +* **Offset 0 (1 byte):** Magic byte (0xe7) + +* **Offset 1 (1 byte):** Version number byte (currently 0x02), 0x01 is for Secure Boot V1. + +* **Offset 2 (2 bytes):** Padding bytes, Reserved. Should be zero. + +* **Offset 4 (32 bytes):** SHA-256 hash of only the image content, not including the signature block. + +* **Offset 36 (384 bytes):** RSA Public Modulus used for signature verification. (value ‘n’ in RFC8017). + +* **Offset 420 (4 bytes):** RSA Public Exponent used for signature verification (value ‘e’ in RFC8017). + +* **Offset 424 (384 bytes):** Precalculated R, derived from ‘n’. + +* **Offset 808 (4 bytes):** Precalculated M’, derived from ‘n’ + +* **Offset 812 (384 bytes):** RSA-PSS Signature result (section 8.1.1 of RFC8017) of image content, computed using following PSS parameters: SHA256 hash, MFG1 function, 0 length salt, default trailer field (0xBC). + +* **Offset 1196:** CRC32 of the preceding 1095 bytes. + +* **Offset 1200 (16 bytes):** Zero padding to length 1216 bytes. + +.. note:: + R and M' are used for hardware-assisted Montgomery Multiplication. + +The remainder of the signature sector is erased flash (0xFF) which allows writing other signature blocks after previous signature block. + +.. _verify_signature-block: + +Verifying the signature Block +----------------------------- + +A signature block is “valid” if the first byte is 0xe7 and a valid CRC32 is stored at offset 1196. Upto 3 signature blocks can be appended to the bootloader or application image in ESP32S2. (ESP32 ECO3: only one key) + +An image is “verified” if the public key stored in any signature block is valid for this device, and if the stored signature is valid for the image data read from flash. + +1. The magic byte, signature block CRC is validated. + +2. Public key digests are generated per signature block and compared with the digests from eFuse. If none of the digests match, the verification process is aborted. + +3. The application image digest is generated and matched with the image digest in the signature blocks. The verification process is aborted is the digests don't match. + +4. The public key is used to verify the signature of the bootloader image, using RSA-PSS (section 8.1.2 of RFC8017) with the image digest calculated in step (3) for comparison. + +- The application signing scheme is set to RSA for secure boot V2 and to ECDSA for secure boot V1. + +.. important:: + It is recommended to use secure boot V2 on the chip versions supporting them. + +.. _secure-boot-v2-bootloader-size: + +Bootloader Size +--------------- + +When secure boot is enabled the bootloader app binary ``bootloader.bin`` may exceed the default bootloader size limit. This is especially likely if flash encryption is enabled as well. The default size limit is 0x7000 (28672) bytes (partition table offset 0x8000 - bootloader offset 0x1000). + +If the bootloader becomes too large, the ESP32 will fail to boot - errors will be logged about either invalid partition table or invalid bootloader checksum. + +Options to work around this are: + +- Reduce :ref:`bootloader log level `. Setting log level to Warning, Error or None all significantly reduce the final binary size (but may make it harder to debug). +- Set :ref:`partition table offset ` to a higher value than 0x8000, to place the partition table later in the flash. This increases the space available for the bootloader. If the :doc:`partition table ` CSV file contains explicit partition offsets, they will need changing so no partition has an offset lower than ``CONFIG_PARTITION_TABLE_OFFSET + 0x1000``. (This includes the default partition CSV files supplied with ESP-IDF.) + +.. _efuse-usage: + +eFuse usage +----------- + +ESP32-ECO3: + +- ABS_DONE_1 - Enables secure boot protection on boot. + +- BLK2 - Stores the SHA-256 digest of the public key. SHA-256 hash of public key modulus, exponent, precalculated R & M’ values (represented as 776 bytes – offsets 36 to 812 - as per the :ref:`signature-block-format`) is written to an eFuse key block. + + +.. _secure-boot-v2-howto: + +How To Enable Secure Boot V2 +---------------------------- + +1. Open the :ref:`project-configuration-menu`, in "Security Features" set "Enable hardware Secure Boot in bootloader" to enable Secure Boot. The chip revision should be changed to revision 3(ESP32- ECO3) to view the Secure Boot V2 option. + +2. To change the chip revision, set "Minimum Supported ESP32 Revision" to Rev 3 in "Component Config" -> "ESP32- Specific", the Secure Boot V2 option can be enabled under "Enable hardware Secure Boot in bootloader" -> "Secure Boot Version". Secure Boot V2 is available for ESP32 ECO3 onwards and in ESP32S2. + +3. Specify the secure boot signing key path. The file can be anywhere on your system. A relative path will be evaluated from the project directory. The file does not need to exist yet. + +4. Set other menuconfig options (as desired). Pay particular attention to the "Bootloader Config" options, as you can only flash the bootloader once. Then exit menuconfig and save your configuration + +5. The first time you run ``make`` or ``idf.py build``, if the signing key is not found then an error message will be printed with a command to generate a signing key via ``espsecure.py generate_signing_key``. + +.. important:: + A signing key generated this way will use the best random number source available to the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak. + +.. important:: + For production environments, we recommend generating the keypair using openssl or another industry standard encryption program. See :ref:`secure-boot-v2-generate-key` for more details. + +6. Run ``idf.py bootloader`` to build a secure boot enabled bootloader. The build output will include a prompt for a flashing command, using ``esptool.py write_flash``. + +7. When you're ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not performed by the build system) and then wait for flashing to complete. + +8. Run ``idf.py flash`` to build and flash the partition table and the just-built app image. The app image will be signed using the signing key you generated in step 4. + +.. note:: ``idf.py flash`` doesn't flash the bootloader if secure boot is enabled. + +9. Reset the ESP32 and it will boot the software bootloader you flashed. The software bootloader will enable secure boot on the chip, and then it verifies the app image signature and boots the app. You should watch the serial console output from the ESP32 to verify that secure boot is enabled and no errors have occurred due to the build configuration. + +.. 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. + +.. note:: If the ESP32 is reset or powered down during the first boot, it will start the process again on the next boot. + +10. On subsequent boots, the secure boot hardware will verify the software bootloader has not changed and the software bootloader will verify the signed app image (using the validated public key portion of its appended signature block). + +.. _secure-boot-v2-generate-key: + +Generating Secure Boot Signing Key +---------------------------------- + +The build system will prompt you with a command to generate a new signing key via ``espsecure.py generate_signing_key``. The --version 2 parameter will generate the RSA 3072 private key for Secure Boot V2. + +The strength of the signing key is proportional to (a) the random number source of the system, and (b) the correctness of the algorithm used. For production devices, we recommend generating signing keys from a system with a quality entropy source, and using the best available RSA key generation utilities. + +For example, to generate a signing key using the openssl command line: + +``` +openssl genrsa -out my_secure_boot_signing_key.pem 3072 +``` + +Remember that the strength of the secure boot system depends on keeping the signing key private. + +.. _remote-sign-v2-image: + +Remote Signing of Images +------------------------ + +For production builds, it can be good practice to use a remote signing server rather than have the signing key on the build machine (which is the default esp-idf secure boot configuration). The espsecure.py command line program can be used to sign app images & partition table data for secure boot, on a remote system. + +To use remote signing, disable the option "Sign binaries during build". The private signing key does not need to be present on the build system. + +After the app image and partition table are built, the build system will print signing steps using espsecure.py:: + + espsecure.py sign_data --version 2 --keyfile PRIVATE_SIGNING_KEY BINARY_FILE + +The above command appends the image signature to the existing binary. You can use the `--output` argument to write the signed binary to a separate file:: + + espsecure.py sign_data --version 2 --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE + +Secure Boot Best Practices +-------------------------- + +* Generate the signing key on a system with a quality source of entropy. +* Keep the signing key private at all times. A leak of this key will compromise the secure boot system. +* Do not allow any third party to observe any aspects of the key generation or signing process using espsecure.py. Both processes are vulnerable to timing or other side-channel attacks. +* Enable all secure boot options in the Secure Boot Configuration. These include flash encryption, disabling of JTAG, disabling BASIC ROM interpeter, and disabling the UART bootloader encrypted flash access. +* Use secure boot in combination with :doc:`flash encryption` to prevent local readout of the flash contents. + +.. _secure-boot-v2-technical-details: + +Technical Details +----------------- + +The following sections contain low-level reference descriptions of various secure boot elements: + +Manual Commands +~~~~~~~~~~~~~~~ + +Secure boot is integrated into the esp-idf build system, so ``make`` or ``idf.py build`` will sign an app image and ``idf.py bootloader`` will produce a signed bootloader if secure signed binaries on build is enabled. + +However, it is possible to use the ``espsecure.py`` tool to make standalone signatures and digests. + +To sign a binary image:: + + espsecure.py sign_data --version 2 --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin + +Keyfile is the PEM file containing an RSA-3072 private signing key. + +.. _secure-boot-v2-and-flash-encr: + +Secure Boot & Flash Encryption +------------------------------ + +If secure boot is used without :doc:`Flash Encryption `, it is possible to launch "time-of-check to time-of-use" attack, where flash contents are swapped after the image is verified and running. Therefore, it is recommended to use both the features together. diff --git a/docs/page_redirects.txt b/docs/page_redirects.txt index a1a6239c0..f46f814f6 100644 --- a/docs/page_redirects.txt +++ b/docs/page_redirects.txt @@ -50,4 +50,7 @@ api-guide/build-system-cmake api-guide/build-system api-guide/ulp-cmake api-guide/ulp api-guide/unit-tests-cmake api-guide/unit-tests -api-reference/network/tcpip_adapter api-reference/network/esp_netif \ No newline at end of file +api-reference/network/tcpip_adapter api-reference/network/esp_netif + +# The 'secure boot' guides are now 'secure boot v1' guides +security/secure-boot.rst security/secure-boot-v1.rst diff --git a/docs/zh_CN/api-guides/index.rst b/docs/zh_CN/api-guides/index.rst index 40ab0e866..09a32d945 100644 --- a/docs/zh_CN/api-guides/index.rst +++ b/docs/zh_CN/api-guides/index.rst @@ -20,7 +20,8 @@ API 指南 JTAG 调试 引导加载程序 分区表 - Secure Boot <../security/secure-boot> + :esp32: Secure Boot <../security/secure-boot-v1> + :esp32: Secure Boot V2 <../security/secure-boot-v2> ULP 协处理器 :esp32: ULP (传统 GNU Make) 单元测试 diff --git a/docs/zh_CN/api-guides/partition-tables.rst b/docs/zh_CN/api-guides/partition-tables.rst index 7f6404e1b..3f355aa88 100644 --- a/docs/zh_CN/api-guides/partition-tables.rst +++ b/docs/zh_CN/api-guides/partition-tables.rst @@ -7,7 +7,9 @@ 每片 {IDF_TARGET_NAME} 的 flash 可以包含多个应用程序,以及多种不同类型的数据(例如校准数据、文件系统数据、参数存储器数据等)。因此,我们需要引入分区表的概念。 -具体来说,{IDF_TARGET_NAME} 在 flash 的 :ref:`默认偏移地址 ` 0x8000 处烧写一张分区表。该分区表的长度为 0xC00 字节(最多可以保存 95 条分区表条目)。分区表数据后还保存着该表的 MD5 校验和,用于验证分区表的完整性。此外,如果芯片使能了 :doc:`安全启动 ` 功能,则该分区表后还会保存签名信息。 +.. only:: esp32 + + 具体来说,{IDF_TARGET_NAME} 在 flash 的 :ref:`默认偏移地址 ` 0x8000 处烧写一张分区表。该分区表的长度为 0xC00 字节(最多可以保存 95 条分区表条目)。分区表数据后还保存着该表的 MD5 校验和,用于验证分区表的完整性。此外,如果芯片使能了 :doc:`安全启动 ` 功能,则该分区表后还会保存签名信息。 分区表中的每个条目都包括以下几个部分:Name(标签)、Type(app、data 等)、SubType 以及在 flash 中的偏移量(分区的加载地址)。 @@ -175,4 +177,4 @@ MD5 校验和 分区表的更新并不会擦除根据之前分区表存储的数据。此时,您可以使用 ``idf.py erase_flash`` 命令或者 ``esptool.py erase_flash`` 命令来擦除 flash 中的所有内容。 -.. _secure boot: security/secure-boot.rst +.. _secure boot: security/secure-boot-v1.rst diff --git a/docs/zh_CN/security/flash-encryption.rst b/docs/zh_CN/security/flash-encryption.rst index 90e749d8f..3caf73b44 100644 --- a/docs/zh_CN/security/flash-encryption.rst +++ b/docs/zh_CN/security/flash-encryption.rst @@ -24,7 +24,9 @@ Flash 加密功能用于加密与 {IDF_TARGET_NAME} 搭载使用的 SPI Flash - 安全启动引导加载程序摘要(如果已启用安全启动) - 分区表中标有“加密”标记的分区 -Flash 加密与 :doc:`安全启动` 功能各自独立,您可以在关闭安全启动的状态下使用 Flash 加密。但是,为了安全的计算机环境,二者应同时使用。在关闭安全启动的状态下,需运行其他配置来确保 Flash 加密的有效性。详细信息可参见 :ref:`flash-encryption-without-secure-boot`。 +.. only:: esp32 + + Flash 加密与 :doc:`安全启动` 功能各自独立,您可以在关闭安全启动的状态下使用 Flash 加密。但是,为了安全的计算机环境,二者应同时使用。在关闭安全启动的状态下,需运行其他配置来确保 Flash 加密的有效性。详细信息可参见 :ref:`flash-encryption-without-secure-boot`。 .. important:: 启用 Flash 加密将限制后续 {IDF_TARGET_NAME} 更新。请务必阅读本文档(包括 :ref:`flash-encryption-limitations`)了解启用 Flash 加密的影响。 @@ -116,7 +118,9 @@ Flash 的加密过程 - 在引导加载程序 config 下选择适当详细程度的日志。 -- 启用 Flash 加密将增大引导加载程序,因而可能需更新分区表偏移。请参见 :ref:`secure-boot-bootloader-size`。 +.. only:: esp32 + + - 启用 Flash 加密将增大引导加载程序,因而可能需更新分区表偏移。请参见 :ref:`secure-boot-bootloader-size`。 - 保存配置并退出。 @@ -310,7 +314,9 @@ Flash 的加密过程 - 在引导加载程序 config 下选择适当详细程度的日志。 -- 启用 Flash 加密将增大引导加载程序,因而可能需要更新分区表偏移。可参见 See :ref:`secure-boot-bootloader-size`。 +.. only:: esp32 + + - 启用 Flash 加密将增大引导加载程序,因而可能需要更新分区表偏移。可参见 See :ref:`secure-boot-bootloader-size`。 - 保存配置并退出。 @@ -347,7 +353,9 @@ Flash 的加密过程 - 在引导加载程序 config 下选择适当详细程度的日志。 -- 启用 Flash 加密将增大引导加载程序,因而可能需要更新分区表偏移。可参见 See :ref:`secure-boot-bootloader-size`。 +.. only:: esp32 + + - 启用 Flash 加密将增大引导加载程序,因而可能需要更新分区表偏移。可参见 See :ref:`secure-boot-bootloader-size`。 - 保存配置并退出。 @@ -467,7 +475,9 @@ Flash 加密的要点 - 如果已启用安全启动,则重新烧录加密设备的引导加载程序则需要“可重新烧录”的安全启动摘要(可参见 :ref:`flash-encryption-and-secure-boot`)。 -.. note:: 同时启用安全启动和 Flash 加密后,引导加载程序 app 二进制文件 ``bootloader.bin`` 可能会过大。参见 :ref:`secure-boot-bootloader-size`。 +.. only:: esp32 + + .. note:: 同时启用安全启动和 Flash 加密后,引导加载程序 app 二进制文件 ``bootloader.bin`` 可能会过大。参见 :ref:`secure-boot-bootloader-size`。 .. important:: 在首次启动加密过程中,请勿中断 {IDF_TARGET_NAME} 的电源。如果电源中断,Flash 的内容将受到破坏,并需要重新烧录未加密数据。而这类重新烧录将不计入烧录限制次数。 @@ -562,7 +572,9 @@ Flash 加密可防止从加密 Flash 中读取明文,从而保护固件防止 - 出于相同原因,攻击者始终可获知一对相邻的 16 字节块(32 字节对齐)何时包含相同内容。因此,在 Flash 上存储敏感数据时应牢记这点,并进行相关设置避免该情况发生(可使用计数器字节或每 16 字节设置不同的值即可)。 -- 单独使用 Flash 加密可能无法防止攻击者修改本设备的固件。为防止设备上运行未经授权的固件,可搭配 Flash 加密使用 :doc:`安全启动 `。 +.. only:: esp32 + + - 单独使用 Flash 加密可能无法防止攻击者修改本设备的固件。为防止设备上运行未经授权的固件,可搭配 Flash 加密使用 :doc:`安全启动 `。 .. _flash-encryption-and-secure-boot: @@ -572,8 +584,12 @@ Flash 加密与安全启动 推荐搭配使用 Flash 加密与安全启动。但是,如果已启用安全启动,则重新烧录设备时会受到其他限制: - :ref:`updating-encrypted-flash-ota` 不受限制(如果新的 app 已使用安全启动签名密钥进行正确签名)。 -- 只有当选择 :ref:`可再次烧录 ` 安全启动模式,且安全启动密钥已预生成并烧录至 {IDF_TARGET_NAME}(可参见 :ref:`安全启动 `),则 :ref:`明文串行 flash 更新 ` 可实现。在该配置下,``idf.py bootloader`` 将生成简化的引导加载程序和安全启动摘要文件,用于在偏移量 0x0 处进行烧录。当进行明文串行重新烧录步骤时,须在烧录其他明文数据前重新烧录此文件。 -- 假设未重新烧录引导加载程序,:ref:`使用预生成的 Flash 加密密钥重新烧录 ` 仍可实现。重新烧录引导加载程序时,需在安全启动配置中启用相同的 :ref:`可重新烧录 ` 选项。 + +.. only:: esp32 + + - 只有当选择 :ref:`可再次烧录 ` 安全启动模式,且安全启动密钥已预生成并烧录至 {IDF_TARGET_NAME}(可参见 :ref:`安全启动 `),则 :ref:`明文串行 flash 更新 ` 可实现。在该配置下,``idf.py bootloader`` 将生成简化的引导加载程序和安全启动摘要文件,用于在偏移量 0x0 处进行烧录。当进行明文串行重新烧录步骤时,须在烧录其他明文数据前重新烧录此文件。 + + - 假设未重新烧录引导加载程序,:ref:`使用预生成的 Flash 加密密钥重新烧录 ` 仍可实现。重新烧录引导加载程序时,需在安全启动配置中启用相同的 :ref:`可重新烧录 ` 选项。 .. _flash-encryption-without-secure-boot: diff --git a/docs/zh_CN/security/secure-boot-v1.rst b/docs/zh_CN/security/secure-boot-v1.rst new file mode 100644 index 000000000..fd3d07baf --- /dev/null +++ b/docs/zh_CN/security/secure-boot-v1.rst @@ -0,0 +1 @@ +.. include:: ../../en/security/secure-boot-v1.rst \ No newline at end of file diff --git a/docs/zh_CN/security/secure-boot-v2.rst b/docs/zh_CN/security/secure-boot-v2.rst new file mode 100644 index 000000000..c5241d557 --- /dev/null +++ b/docs/zh_CN/security/secure-boot-v2.rst @@ -0,0 +1 @@ +.. include:: ../../en/security/secure-boot-v2.rst \ No newline at end of file diff --git a/docs/zh_CN/security/secure-boot.rst b/docs/zh_CN/security/secure-boot.rst deleted file mode 100644 index 8f46c8e4f..000000000 --- a/docs/zh_CN/security/secure-boot.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../en/security/secure-boot.rst \ No newline at end of file