diff --git a/ChangeLog.d/mbedtls_pk_ecc_set_pubkey.txt b/ChangeLog.d/mbedtls_pk_ecc_set_pubkey.txt new file mode 100644 index 0000000000..44906298da --- /dev/null +++ b/ChangeLog.d/mbedtls_pk_ecc_set_pubkey.txt @@ -0,0 +1,3 @@ +Security + * Fix a 1-byte buffer overread when parsing a malformed ECC public key + in the PK module. diff --git a/library/pk_ecc.c b/library/pk_ecc.c index 86218fffc8..20fe953d01 100644 --- a/library/pk_ecc.c +++ b/library/pk_ecc.c @@ -205,13 +205,19 @@ int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + /* We need to read the first byte to determine the format (compressed, + * uncompressed or 0). */ + if (pub_len == 0) { + return MBEDTLS_ERR_PK_INVALID_PUBKEY; + } + /* Load the key */ if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) { /* Format directly supported by PSA: * - non-Weierstrass curves that only have one format; * - uncompressed format for Weierstrass curves. */ if (pub_len > sizeof(pk->pub_raw)) { - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; + return MBEDTLS_ERR_PK_INVALID_PUBKEY; } memcpy(pk->pub_raw, pub, pub_len); pk->pub_raw_len = pub_len; diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py index 9bf01248ae..83264b85ea 100755 --- a/tests/scripts/analyze_outcomes.py +++ b/tests/scripts/analyze_outcomes.py @@ -449,8 +449,8 @@ class DriverVSReference_no_ecp_at_all(outcome_analysis.DriverVSReference): # consequence compressed points are supported in the reference # component but not in the accelerated one, so they should be skipped # while checking driver's coverage. - re.compile(r'Parse EC Key .*compressed\)'), - re.compile(r'Parse Public EC Key .*compressed\)'), + re.compile(r'Parse EC Key .*(?len); + memcpy(key_copy, key_data->x, key_data->len); + + res = mbedtls_pk_parse_public_key(&ctx, key_copy, key_data->len); + + TEST_EQUAL(res, result); + + if (res == 0) { + TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY)); + +#if defined(MBEDTLS_PSA_CRYPTO_C) + PSA_INIT(); + if (pk_can_ecdsa(&ctx)) { + TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH)); + TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE)); + } +#endif + } + +exit: + mbedtls_pk_free(&ctx); + PSA_DONE(); + mbedtls_free(key_copy); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_PK_HAVE_ECC_KEYS */ void pk_parse_public_keyfile_ec(char *key_file, int result) {