diff --git a/.flake8 b/.flake8 index 34bb7118afdf..f7792af9806a 100644 --- a/.flake8 +++ b/.flake8 @@ -141,7 +141,7 @@ exclude = __pycache__, # submodules components/esptool_py/esptool, - components/micro-ecc/micro-ecc, + components/bootloader/subproject/components/micro-ecc/micro-ecc, components/nghttp/nghttp2, components/libsodium/libsodium, components/json/cJSON, diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b4c3415664b1..bc8bff348517 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -46,7 +46,7 @@ variables: find . -name '.git' -not -path './.git' -printf '%P\n' | sed 's|/.git||' | xargs -I {} sh -c ' - grep -q {} .gitmodules + grep -q "path = {}" .gitmodules || (echo "Removing {}, has .git directory but not in .gitmodules file" && rm -rf {});' diff --git a/.gitmodules b/.gitmodules index 9c1e24c7b5ce..c7bb6c9d3ec1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,8 +6,8 @@ path = components/bt/lib url = https://github.com/espressif/esp32-bt-lib.git -[submodule "components/micro-ecc/micro-ecc"] - path = components/micro-ecc/micro-ecc +[submodule "components/bootloader/subproject/components/micro-ecc/micro-ecc"] + path = components/bootloader/subproject/components/micro-ecc/micro-ecc url = https://github.com/kmackay/micro-ecc.git [submodule "components/coap/libcoap"] diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index f7d2282e0358..e800007f8012 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -108,13 +108,6 @@ static esp_err_t image_validate(const esp_partition_t *partition, esp_image_load return ESP_ERR_OTA_VALIDATE_FAILED; } -#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE - esp_err_t ret = esp_secure_boot_verify_signature(partition->address, data.image_len); - if (ret != ESP_OK) { - return ESP_ERR_OTA_VALIDATE_FAILED; - } -#endif - return ESP_OK; } diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index a51ff6f0254f..80973473d87b 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -234,6 +234,7 @@ menu "Security features" config SECURE_SIGNED_ON_UPDATE bool default y + select MBEDTLS_ECP_DP_SECP256R1_ENABLED depends on SECURE_BOOT_ENABLED || SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT config SECURE_SIGNED_APPS diff --git a/components/micro-ecc/CMakeLists.txt b/components/bootloader/subproject/components/micro-ecc/CMakeLists.txt similarity index 100% rename from components/micro-ecc/CMakeLists.txt rename to components/bootloader/subproject/components/micro-ecc/CMakeLists.txt diff --git a/components/micro-ecc/component.mk b/components/bootloader/subproject/components/micro-ecc/component.mk similarity index 100% rename from components/micro-ecc/component.mk rename to components/bootloader/subproject/components/micro-ecc/component.mk diff --git a/components/micro-ecc/micro-ecc b/components/bootloader/subproject/components/micro-ecc/micro-ecc similarity index 100% rename from components/micro-ecc/micro-ecc rename to components/bootloader/subproject/components/micro-ecc/micro-ecc diff --git a/components/bootloader_support/CMakeLists.txt b/components/bootloader_support/CMakeLists.txt index 3bd3e9b1481e..244dad5dea32 100644 --- a/components/bootloader_support/CMakeLists.txt +++ b/components/bootloader_support/CMakeLists.txt @@ -54,7 +54,7 @@ else() set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader") set(COMPONENT_REQUIRES) - set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls micro-ecc efuse) + set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls efuse) endif() register_component() diff --git a/components/bootloader_support/src/secure_boot_signatures.c b/components/bootloader_support/src/secure_boot_signatures.c index eb2d6a702fa6..e28e8a2729d2 100644 --- a/components/bootloader_support/src/secure_boot_signatures.c +++ b/components/bootloader_support/src/secure_boot_signatures.c @@ -19,13 +19,13 @@ #include "esp_image_format.h" #include "esp_secure_boot.h" -#include "uECC.h" - #ifdef BOOTLOADER_BUILD #include "esp32/rom/sha.h" +#include "uECC.h" typedef SHA_CTX sha_context; #else #include "mbedtls/sha256.h" +#include "mbedtls/x509.h" #endif static const char* TAG = "secure_boot"; @@ -71,7 +71,6 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest) { ptrdiff_t keylen; - bool is_valid; keylen = signature_verification_key_end - signature_verification_key_start; if(keylen != SIGNATURE_VERIFICATION_KEYLEN) { @@ -86,6 +85,8 @@ esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block ESP_LOGD(TAG, "Verifying secure boot signature"); +#ifdef BOOTLOADER_BUILD + bool is_valid; is_valid = uECC_verify(signature_verification_key_start, image_digest, DIGEST_LEN, @@ -93,4 +94,52 @@ esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block uECC_secp256r1()); ESP_LOGD(TAG, "Verification result %d", is_valid); return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID; +#else /* BOOTLOADER_BUILD */ + int ret; + mbedtls_mpi r, s; + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + /* Extract r and s components from RAW ECDSA signature of 64 bytes */ + #define ECDSA_INTEGER_LEN 32 + ret = mbedtls_mpi_read_binary(&r, &sig_block->signature[0], ECDSA_INTEGER_LEN); + if (ret != 0) { + ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(1), err:%d", ret); + return ESP_FAIL; + } + + ret = mbedtls_mpi_read_binary(&s, &sig_block->signature[ECDSA_INTEGER_LEN], ECDSA_INTEGER_LEN); + if (ret != 0) { + ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(2), err:%d", ret); + mbedtls_mpi_free(&r); + return ESP_FAIL; + } + + /* Initialise ECDSA context */ + mbedtls_ecdsa_context ecdsa_context; + mbedtls_ecdsa_init(&ecdsa_context); + + mbedtls_ecp_group_load(&ecdsa_context.grp, MBEDTLS_ECP_DP_SECP256R1); + size_t plen = mbedtls_mpi_size(&ecdsa_context.grp.P); + if (keylen != 2*plen) { + ESP_LOGE(TAG, "Incorrect ECDSA key length %d", keylen); + ret = ESP_FAIL; + goto cleanup; + } + + /* Extract X and Y components from ECDSA public key */ + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.Q.X, signature_verification_key_start, plen)); + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.Q.Y, signature_verification_key_start + plen, plen)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ecdsa_context.Q.Z, 1)); + + ret = mbedtls_ecdsa_verify(&ecdsa_context.grp, image_digest, DIGEST_LEN, &ecdsa_context.Q, &r, &s); + ESP_LOGD(TAG, "Verification result %d", ret); + +cleanup: + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + mbedtls_ecdsa_free(&ecdsa_context); + return ret == 0 ? ESP_OK : ESP_ERR_IMAGE_INVALID; +#endif /* !BOOTLOADER_BUILD */ } diff --git a/tools/ci/mirror-list.txt b/tools/ci/mirror-list.txt index fbb8f154483d..4d83a6c99cbe 100644 --- a/tools/ci/mirror-list.txt +++ b/tools/ci/mirror-list.txt @@ -8,7 +8,7 @@ components/json/cJSON @GENERAL_MIRROR_SERV components/libsodium/libsodium @GENERAL_MIRROR_SERVER@/idf/libsodium.git ALLOW_TO_SYNC_FROM_PUBLIC components/mbedtls/mbedtls @GENERAL_MIRROR_SERVER@/idf/mbedtls.git ALLOW_TO_SYNC_FROM_PUBLIC components/expat/expat @GENERAL_MIRROR_SERVER@/idf/libexpat.git ALLOW_TO_SYNC_FROM_PUBLIC -components/micro-ecc/micro-ecc @GENERAL_MIRROR_SERVER@/idf/micro-ecc.git ALLOW_TO_SYNC_FROM_PUBLIC +components/bootloader/subproject/components/micro-ecc/micro-ecc @GENERAL_MIRROR_SERVER@/idf/micro-ecc.git ALLOW_TO_SYNC_FROM_PUBLIC components/nghttp/nghttp2 @GENERAL_MIRROR_SERVER@/idf/nghttp2.git ALLOW_TO_SYNC_FROM_PUBLIC components/spiffs/spiffs @GENERAL_MIRROR_SERVER@/idf/spiffs.git ALLOW_TO_SYNC_FROM_PUBLIC components/asio/asio @GENERAL_MIRROR_SERVER@/idf/asio.git