From 331fd7f79fc7292bb6f8653521feacd00b7967cb Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Thu, 5 Sep 2024 12:17:17 +0530 Subject: [PATCH 1/2] fix(mbedtls/port): Check signature hash length before using ECDSA hardware --- components/mbedtls/port/ecdsa/ecdsa_alt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index 1f46381987..752b046d0c 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -674,7 +674,7 @@ int __wrap_mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, const mbedtls_mpi *r, const mbedtls_mpi *s) { - if (grp->id == MBEDTLS_ECP_DP_SECP192R1 || grp->id == MBEDTLS_ECP_DP_SECP256R1) { + if ((grp->id == MBEDTLS_ECP_DP_SECP192R1 || grp->id == MBEDTLS_ECP_DP_SECP256R1) && blen == ECDSA_SHA_LEN) { return esp_ecdsa_verify(grp, buf, blen, Q, r, s); } else { return __real_mbedtls_ecdsa_verify(grp, buf, blen, Q, r, s); From c4f60d91f16c293b9b66fa39adf3d996e38b85fd Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Thu, 5 Sep 2024 12:19:00 +0530 Subject: [PATCH 2/2] feat(mbedtls): Wrap mbedtls_ecdsa_read_signature to use ECDSA hardware when possible --- components/mbedtls/CMakeLists.txt | 3 + components/mbedtls/port/ecdsa/ecdsa_alt.c | 114 +++++++++++++++++++++- 2 files changed, 113 insertions(+), 4 deletions(-) diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index b7801b6b74..8a3080fd60 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -283,6 +283,9 @@ if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY) if(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY) target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_verify") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_verify_restartable") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_read_signature") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_read_signature_restartable") endif() endif() diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index 752b046d0c..e365702916 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -15,6 +15,7 @@ #include "esp_private/esp_crypto_lock_internal.h" #include "mbedtls/error.h" #include "mbedtls/ecdsa.h" +#include "mbedtls/asn1.h" #include "mbedtls/asn1write.h" #include "mbedtls/platform_util.h" #include "ecdsa/ecdsa_alt.h" @@ -653,6 +654,37 @@ static int esp_ecdsa_verify(mbedtls_ecp_group *grp, return ret; } +/* + * Verify ECDSA signature of hashed message + */ +extern int __real_mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *r, + const mbedtls_mpi *s, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +int __wrap_mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *r, + const mbedtls_mpi *s, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +int __wrap_mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *r, + const mbedtls_mpi *s, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + if ((grp->id == MBEDTLS_ECP_DP_SECP192R1 || grp->id == MBEDTLS_ECP_DP_SECP256R1) && blen == ECDSA_SHA_LEN) { + return esp_ecdsa_verify(grp, buf, blen, Q, r, s); + } else { + return __real_mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, rs_ctx); + } +} + /* * Verify ECDSA signature of hashed message */ @@ -674,10 +706,84 @@ int __wrap_mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, const mbedtls_mpi *r, const mbedtls_mpi *s) { - if ((grp->id == MBEDTLS_ECP_DP_SECP192R1 || grp->id == MBEDTLS_ECP_DP_SECP256R1) && blen == ECDSA_SHA_LEN) { - return esp_ecdsa_verify(grp, buf, blen, Q, r, s); - } else { - return __real_mbedtls_ecdsa_verify(grp, buf, blen, Q, r, s); + return __wrap_mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL); +} + + +int __real_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +int __wrap_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +int __wrap_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char *p = (unsigned char *) sig; + const unsigned char *end = sig + slen; + size_t len; + mbedtls_mpi r, s; + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; } + + if (p + len != end) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + goto cleanup; + } + + if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 || + (ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0) { + ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + if ((ret = __wrap_mbedtls_ecdsa_verify_restartable(&ctx->MBEDTLS_PRIVATE(grp), hash, hlen, + &ctx->MBEDTLS_PRIVATE(Q), &r, &s, NULL)) != 0) { + goto cleanup; + } + + /* At this point we know that the buffer starts with a valid signature. + * Return 0 if the buffer just contains the signature, and a specific + * error code if the valid signature is followed by more data. */ + if (p != end) { + ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; + } + +cleanup: + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + + return ret; +} + + +int __real_mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen); + +int __wrap_mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen); + +int __wrap_mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen) +{ + return __wrap_mbedtls_ecdsa_read_signature_restartable( + ctx, hash, hlen, sig, slen, NULL); } #endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY */