From b79606ca37c5f514c18f4e2d40a4ecc193932527 Mon Sep 17 00:00:00 2001 From: Supreet Deshpande Date: Tue, 25 Feb 2020 01:22:46 +0530 Subject: [PATCH] feat/secure_boot_v2: Adding tools support for secure boot v2 ECO3 --- tools/ldgen/samples/sdkconfig | 2 +- tools/test_apps/README.md | 1 + .../security/secure_boot/CMakeLists.txt | 7 ++ tools/test_apps/security/secure_boot/Makefile | 9 ++ .../test_apps/security/secure_boot/README.md | 53 ++++++++++ .../security/secure_boot/main/CMakeLists.txt | 4 + .../security/secure_boot/main/component.mk | 5 + .../secure_boot/main/secure_boot_main.c | 96 +++++++++++++++++++ .../security/secure_boot/sdkconfig.ci.00 | 6 ++ .../security/secure_boot/sdkconfig.ci.01 | 4 + .../security/secure_boot/sdkconfig.ci.02 | 4 + .../security/secure_boot/test_ecdsa_key.pem | 5 + .../secure_boot/test_rsa_3072_key.pem | 39 ++++++++ 13 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 tools/test_apps/security/secure_boot/CMakeLists.txt create mode 100644 tools/test_apps/security/secure_boot/Makefile create mode 100644 tools/test_apps/security/secure_boot/README.md create mode 100644 tools/test_apps/security/secure_boot/main/CMakeLists.txt create mode 100644 tools/test_apps/security/secure_boot/main/component.mk create mode 100644 tools/test_apps/security/secure_boot/main/secure_boot_main.c create mode 100644 tools/test_apps/security/secure_boot/sdkconfig.ci.00 create mode 100644 tools/test_apps/security/secure_boot/sdkconfig.ci.01 create mode 100644 tools/test_apps/security/secure_boot/sdkconfig.ci.02 create mode 100644 tools/test_apps/security/secure_boot/test_ecdsa_key.pem create mode 100644 tools/test_apps/security/secure_boot/test_rsa_3072_key.pem diff --git a/tools/ldgen/samples/sdkconfig b/tools/ldgen/samples/sdkconfig index 9f4e07d5f..a11335693 100644 --- a/tools/ldgen/samples/sdkconfig +++ b/tools/ldgen/samples/sdkconfig @@ -21,7 +21,7 @@ CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y # # Security features # -CONFIG_SECURE_BOOT_ENABLED= +CONFIG_SECURE_BOOT= CONFIG_SECURE_FLASH_ENC_ENABLED= # diff --git a/tools/test_apps/README.md b/tools/test_apps/README.md index 3bb1e7e12..0d2187770 100644 --- a/tools/test_apps/README.md +++ b/tools/test_apps/README.md @@ -23,6 +23,7 @@ The test apps should be grouped into subdirectories by category. Categories are: * `protocols` contains test of protocol interactions. * `network` contains system network tests * `system` contains tests on the internal chip features, debugging and development tools. +* `security` contains tests on the chip security features. # Test Apps local execution diff --git a/tools/test_apps/security/secure_boot/CMakeLists.txt b/tools/test_apps/security/secure_boot/CMakeLists.txt new file mode 100644 index 000000000..803addc12 --- /dev/null +++ b/tools/test_apps/security/secure_boot/CMakeLists.txt @@ -0,0 +1,7 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +set(SUPPORTED_TARGETS esp32) # Secure Boot not currently supported for ESP32-S2beta +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(secure_boot) diff --git a/tools/test_apps/security/secure_boot/Makefile b/tools/test_apps/security/secure_boot/Makefile new file mode 100644 index 000000000..092b5481a --- /dev/null +++ b/tools/test_apps/security/secure_boot/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := secure_boot + +include $(IDF_PATH)/make/project.mk + diff --git a/tools/test_apps/security/secure_boot/README.md b/tools/test_apps/security/secure_boot/README.md new file mode 100644 index 000000000..b713a1945 --- /dev/null +++ b/tools/test_apps/security/secure_boot/README.md @@ -0,0 +1,53 @@ +# Secure Boot + +The example checks if the secure boot feature is enabled/disabled and if enabled prints the secure boot version (Version 1 / Version 2) and FLASH_CRYPT_CNT eFuse value. + +## How to use example + +### Hardware Required + +ESP32 (supports Secure Boot V1) or ESP32-ECO3 (supports Secure Boot V2 & Secure Boot V1). It is recommended to use Secure Boot V2 from ESP32-ECO3 onwards. + +### Configure the project + +``` +idf.py menuconfig +``` + +* Set serial port under Serial Flasher Options. + +* Enable the `Enable hardware Secure Boot` under Security Features. Default version for ESP32 is Secure Boot V1. The chip revision should be changed to revision 3(ESP32- ECO3) to view the Secure Boot V2 option. + +* To change the chip revision, set "Component Config" -> "ESP32- Specific"->"Minimum Supported ESP32 Revision" to Rev 3. Now, set Secure Boot V2 option can now be enabled under "Enable hardware Secure Boot in bootloader" -> "Secure Boot Version". + +* Specify the apt secure boot signing key path. If not present generate one using `python $IDF_PATH/components/esptool_py/esptool/espsecure.py generate_signing_key --version {VERSION} secure_boot_signing_key.pem` + +* Ensure Bootloader log verbosity is Info under Bootloader config. + +* Select Single factory app, no OTA under Partition Table options. Change the partition table offset to 0xb000 from 0x8000 since after enabling secure boot the size of bootloader is increased. + +### Build and Flash + +- The below steps can be used in any application to enable secure boot. + +- Secure Boot is an irreversible operation, please read the Secure Boot section in ESP-IDF Programming Manual. + +- Secure boot will be enabled on building the project after enabling hardware secure boot feature in _Security features_ in menuconfig and flashing it to the board FOR THE FIRST TIME. + +- The bootloader will not be automatically flashed when secure boot is enabled. Running `idf.py bootloader` will print a command to flash the bootloader on the ESP32. Run this command manually to flash the bootloader. + +Run following command to program the partition table and application on the ESP32 and monitor the output: +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +- 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). + +## Example Output + +## Troubleshooting + diff --git a/tools/test_apps/security/secure_boot/main/CMakeLists.txt b/tools/test_apps/security/secure_boot/main/CMakeLists.txt new file mode 100644 index 000000000..87f374903 --- /dev/null +++ b/tools/test_apps/security/secure_boot/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_SRCS "secure_boot_main.c") +set(COMPONENT_ADD_INCLUDEDIRS "") + +register_component() diff --git a/tools/test_apps/security/secure_boot/main/component.mk b/tools/test_apps/security/secure_boot/main/component.mk new file mode 100644 index 000000000..0b9d7585e --- /dev/null +++ b/tools/test_apps/security/secure_boot/main/component.mk @@ -0,0 +1,5 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/tools/test_apps/security/secure_boot/main/secure_boot_main.c b/tools/test_apps/security/secure_boot/main/secure_boot_main.c new file mode 100644 index 000000000..e4b8f452f --- /dev/null +++ b/tools/test_apps/security/secure_boot/main/secure_boot_main.c @@ -0,0 +1,96 @@ +/* Flash encryption Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "soc/efuse_reg.h" +#include "esp_efuse.h" +#include "esp_system.h" +#include "esp_spi_flash.h" +#include "esp_log.h" +#include "esp_efuse_table.h" +#include + +static void example_print_chip_info(void); +static void example_secure_boot_status(void); + +#define TAG "example_secure_boot" + +void app_main(void) +{ + printf("\nExample to check Secure Boot status\n"); + + example_print_chip_info(); + example_secure_boot_status(); +} + + +static void example_print_chip_info(void) +{ + /* Print chip information */ + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + printf("This is ESP32 chip with %d CPU cores, WiFi%s%s, ", + chip_info.cores, + (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); + + printf("silicon revision %d, ", chip_info.revision); + + printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024), + (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); +} + +#define DIGEST_LEN 32 + +static void example_secure_boot_status(void) +{ + uint32_t efuse_block0 = REG_READ(EFUSE_BLK0_RDATA6_REG); + +#ifdef CONFIG_ESP32_REV_MIN_3 + uint8_t efuse_trusted_digest[DIGEST_LEN] = {0}, i; + ESP_LOGI(TAG, "Checking for secure boot v2.."); + if(efuse_block0 & EFUSE_RD_ABS_DONE_1) { + ESP_LOGI(TAG, "ABS_DONE_1 is set. Secure Boot V2 enabled"); + memcpy(efuse_trusted_digest, (uint8_t *)EFUSE_BLK2_RDATA0_REG, DIGEST_LEN); + ESP_LOGI(TAG, "Reading the public key digest from BLK2."); + for (i = 0; i < DIGEST_LEN; i++) { + ESP_LOGI(TAG, "%02x \t", efuse_trusted_digest[i]); + } + return; + } else { + ESP_LOGI(TAG, "Secure boot v2 not enabled. Enable Secure Boot V2 in menuconfig, build & flash again."); + } +#endif + + ESP_LOGI(TAG, "Checking for secure boot v1.."); + uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG); + if (efuse_block0 & EFUSE_RD_ABS_DONE_0) { + ESP_LOGI(TAG, "ABS_DONE_0 is set. Secure Boot V1 enabled"); +#ifdef CONFIG_ESP32_REV_MIN_3 + ESP_LOGW(TAG, "This chip version supports Secure Boot V2. It is recommended to use Secure Boot V2."); +#endif + bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2; + bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2; + + ESP_LOGI(TAG, "Checking the integrityof the key in BLK2.."); + if (!efuse_key_read_protected) { + ESP_LOGE(TAG, "Key is not read protected. Refusing to blow secure boot efuse."); + return; + } + if (!efuse_key_write_protected) { + ESP_LOGE(TAG, "Key is not write protected. Refusing to blow secure boot efuse."); + return; + } + ESP_LOGI(TAG, "Key is read/write protected in eFuse."); + return; + } else { + ESP_LOGI(TAG, "Secure Boot V1 not enabled. Enable Secure Boot in menuconfig, build & flash again."); + } +} \ No newline at end of file diff --git a/tools/test_apps/security/secure_boot/sdkconfig.ci.00 b/tools/test_apps/security/secure_boot/sdkconfig.ci.00 new file mode 100644 index 000000000..2f672979c --- /dev/null +++ b/tools/test_apps/security/secure_boot/sdkconfig.ci.00 @@ -0,0 +1,6 @@ +# Secure Boot V2 - ESP-ECO3+ +CONFIG_SECURE_BOOT=y +CONFIG_ESP32_REV_MIN_3=y +CONFIG_SECURE_BOOT_V2_ENABLED=y +CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES=y +CONFIG_SECURE_BOOT_SIGNING_KEY="test_rsa_3072_key.pem" diff --git a/tools/test_apps/security/secure_boot/sdkconfig.ci.01 b/tools/test_apps/security/secure_boot/sdkconfig.ci.01 new file mode 100644 index 000000000..808cd998d --- /dev/null +++ b/tools/test_apps/security/secure_boot/sdkconfig.ci.01 @@ -0,0 +1,4 @@ +# Secure Boot V1 +CONFIG_SECURE_BOOT=y +CONFIG_SECURE_BOOT_V1_ENABLED=y +CONFIG_SECURE_BOOT_SIGNING_KEY="test_ecdsa_key.pem" diff --git a/tools/test_apps/security/secure_boot/sdkconfig.ci.02 b/tools/test_apps/security/secure_boot/sdkconfig.ci.02 new file mode 100644 index 000000000..36d9e172a --- /dev/null +++ b/tools/test_apps/security/secure_boot/sdkconfig.ci.02 @@ -0,0 +1,4 @@ +# ECDSA App signing without secure boot +CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT=y +CONFIG_SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT=y +CONFIG_SECURE_BOOT_SIGNING_KEY="test_ecdsa_key.pem" diff --git a/tools/test_apps/security/secure_boot/test_ecdsa_key.pem b/tools/test_apps/security/secure_boot/test_ecdsa_key.pem new file mode 100644 index 000000000..1c424f7c3 --- /dev/null +++ b/tools/test_apps/security/secure_boot/test_ecdsa_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIJLB2fFAa7istjO0AWfEbvJM8Kn0T+R38GXalwX3oP6GoAoGCCqGSM49 +AwEHoUQDQgAEy2N3ohJ1hIjU2AHNyVKGafSrmGhizG1/xOTOtASbJpiVI3ccUVXI +zrDSnrTwg331qOAT7WWkY1p4ixZvP6HWzA== +-----END EC PRIVATE KEY----- diff --git a/tools/test_apps/security/secure_boot/test_rsa_3072_key.pem b/tools/test_apps/security/secure_boot/test_rsa_3072_key.pem new file mode 100644 index 000000000..9e8a52e2a --- /dev/null +++ b/tools/test_apps/security/secure_boot/test_rsa_3072_key.pem @@ -0,0 +1,39 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY-----