From d5d81bdb25f94ee539af73ca28b9002efb732fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82owik?= Date: Tue, 3 Mar 2026 23:01:12 +0100 Subject: [PATCH 1/6] Add failing tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Słowik --- framework | 2 +- tests/suites/test_suite_pkparse.data | 36 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/framework b/framework index 9b92164c47..b8ad4825d8 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 9b92164c47fdaecb2600b417733507e2a105c3a5 +Subproject commit b8ad4825d80a8956b5c8953152443dcfc224c295 diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data index ead0572203..30bee6a004 100644 --- a/tests/suites/test_suite_pkparse.data +++ b/tests/suites/test_suite_pkparse.data @@ -1191,6 +1191,14 @@ Parse Public EC Key #4b (RFC 5480, secp256r1, DER) depends_on:PSA_WANT_ECC_SECP_R1_256 pk_parse_public_keyfile_ec:"../framework/data_files/ec_256_pub.der":0 +Parse Public EC Key #4c (RFC 5480, secp256r1, explicit) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_256_pub.expl.pem":0 + +Parse Public EC Key #4d (RFC 5480, secp256r1, explicit, DER) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_256_pub.expl.der":0 + Parse Public EC Key #5 (RFC 5480, secp384r1) depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ECC_SECP_R1_384 pk_parse_public_keyfile_ec:"../framework/data_files/ec_384_pub.pem":0 @@ -1199,6 +1207,10 @@ Parse Public EC Key #5a (RFC 5480, secp384r1, compressed) depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_SECP384R1_ENABLED pk_parse_public_keyfile_ec:"../framework/data_files/ec_384_pub.comp.pem":0 +Parse Public EC Key #5b (RFC 5480, secp384r1, explicit) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_384_pub.expl.pem":0 + Parse Public EC Key #6 (RFC 5480, secp521r1) depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ECC_SECP_R1_521 pk_parse_public_keyfile_ec:"../framework/data_files/ec_521_pub.pem":0 @@ -1207,6 +1219,14 @@ Parse Public EC Key #6a (RFC 5480, secp521r1, compressed) depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_SECP521R1_ENABLED pk_parse_public_keyfile_ec:"../framework/data_files/ec_521_pub.comp.pem":0 +Parse Public EC Key #6b (RFC 5480, secp521r1, explicit) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_521_pub.expl.pem":0 + +Parse Public EC Key #6c (RFC 5480, secp521r1, explicit, DER) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_521_pub.expl.der":0 + Parse Public EC Key #7 (RFC 5480, brainpoolP256r1) depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ECC_BRAINPOOL_P_R1_256 pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp256_pub.pem":0 @@ -1215,6 +1235,10 @@ Parse Public EC Key #7a (RFC 5480, brainpoolP256r1, compressed) depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_BP256R1_ENABLED pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp256_pub.comp.pem":0 +Parse Public EC Key #7b (RFC 5480, brainpoolP256r1, explicit) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP256R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp256_pub.expl.pem":0 + Parse Public EC Key #8 (RFC 5480, brainpoolP384r1) depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ECC_BRAINPOOL_P_R1_384 pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp384_pub.pem":0 @@ -1223,6 +1247,10 @@ Parse Public EC Key #8a (RFC 5480, brainpoolP384r1, compressed) depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_BP384R1_ENABLED pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp384_pub.comp.pem":0 +Parse Public EC Key #8b (RFC 5480, brainpoolP384r1, explicit) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP384R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp384_pub.expl.pem":0 + Parse Public EC Key #9 (RFC 5480, brainpoolP512r1) depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ECC_BRAINPOOL_P_R1_512 pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp512_pub.pem":0 @@ -1231,6 +1259,14 @@ Parse Public EC Key #9a (RFC 5480, brainpoolP512r1, compressed) depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_BP512R1_ENABLED pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp512_pub.comp.pem":0 +Parse Public EC Key #9b (RFC 5480, brainpoolP512r1, explicit) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP512R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp512_pub.expl.pem":0 + +Parse Public EC Key #9c (RFC 5480, brainpoolP512r1, explicit, DER) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP512R1_ENABLED +pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp512_pub.expl.der":0 + Parse Public EC Key #10 (RFC 8410, DER, X25519) depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ECC_MONTGOMERY_255 pk_parse_public_keyfile_ec:"../framework/data_files/ec_x25519_pub.der":0 From 337e93d6b7c2b63db8514ae809331eb8e4bce369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82owik?= Date: Wed, 4 Mar 2026 15:05:14 +0100 Subject: [PATCH 2/6] Fix explicit curve import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Słowik --- extras/pkparse.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/extras/pkparse.c b/extras/pkparse.c index ae3ef58364..f0aba9fd3c 100644 --- a/extras/pkparse.c +++ b/extras/pkparse.c @@ -104,7 +104,9 @@ static int pk_group_from_specified(const mbedtls_asn1_buf *params, mbedtls_ecp_g unsigned char *p = params->p; const unsigned char *const end = params->p + params->len; const unsigned char *end_field, *end_curve; + mbedtls_mpi tmp; size_t len; + size_t plen; int ver; /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ @@ -184,6 +186,20 @@ static int pk_group_from_specified(const mbedtls_asn1_buf *params, mbedtls_ecp_g (ret = mbedtls_mpi_read_binary(&grp->A, p, len)) != 0) { return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); } + /* + * If A == -3 mod p, the group is stored with an empty A parameter, + * see mbedtls_ecp_group_a_is_minus_3 + */ + mbedtls_mpi_init(&tmp); + if((ret = mbedtls_mpi_sub_int(&tmp, &grp->P, 3)) != 0) { + mbedtls_mpi_free(&tmp); + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); + } + if(mbedtls_mpi_cmp_mpi(&tmp, &grp->A) == 0) { + mbedtls_mpi_free(&grp->A); + mbedtls_mpi_init(&grp->A); + } + mbedtls_mpi_free(&tmp); p += len; @@ -211,20 +227,30 @@ static int pk_group_from_specified(const mbedtls_asn1_buf *params, mbedtls_ecp_g return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); } - if ((ret = mbedtls_ecp_point_read_binary(grp, &grp->G, - (const unsigned char *) p, len)) != 0) { + /* + * We can't read the point using mbedtls_ecp_point_read_binary, + * as it recursively uses grp->G form to select the key format. + * Instead we manually parse the point. + */ + plen = mbedtls_mpi_size(&grp->P); + if (len == 2 * plen + 1 && p[0] == 0x04) { + if (mbedtls_mpi_read_binary(&grp->G.X, p + 1, plen) != 0 || + mbedtls_mpi_read_binary(&grp->G.Y, p + 1 + plen, plen) != 0 || + mbedtls_mpi_lset(&grp->G.Z, 1) != 0) { + return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; + } + } else if (len == plen + 1 && (p[0] == 0x02 || p[0] == 0x03)) { /* * If we can't read the point because it's compressed, cheat by * reading only the X coordinate and the parity bit of Y. */ - if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || - (p[0] != 0x02 && p[0] != 0x03) || - len != mbedtls_mpi_size(&grp->P) + 1 || - mbedtls_mpi_read_binary(&grp->G.X, p + 1, len - 1) != 0 || + if (mbedtls_mpi_read_binary(&grp->G.X, p + 1, plen) != 0 || mbedtls_mpi_lset(&grp->G.Y, p[0] - 2) != 0 || mbedtls_mpi_lset(&grp->G.Z, 1) != 0) { return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; } + } else { + return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; } p += len; From 8531dedab6c785e9d435f3c7450cba6cb978fbbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82owik?= Date: Wed, 4 Mar 2026 16:27:14 +0100 Subject: [PATCH 3/6] Add changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Słowik --- ChangeLog.d/fix-pk_group_from_specified.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ChangeLog.d/fix-pk_group_from_specified.txt diff --git a/ChangeLog.d/fix-pk_group_from_specified.txt b/ChangeLog.d/fix-pk_group_from_specified.txt new file mode 100644 index 0000000000..acec74c398 --- /dev/null +++ b/ChangeLog.d/fix-pk_group_from_specified.txt @@ -0,0 +1,6 @@ +Bugfix: + * Fix `pk_group_from_specified` self-referencing group generator G while loading G. + * Fix `pk_group_from_specified` not accounting for the a = p-3 internal representation. + * Fix `pk_parse_public_key` failing to load keys with explicit curve parameters. + Fixes #4314 + From 638764cc503b9f6466ffc40e9217868442bef6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82owik?= Date: Thu, 5 Mar 2026 14:43:03 +0100 Subject: [PATCH 4/6] Add depdencency on MBEDTLS_PK_PARSE_EC_EXTENDED to the new (explicit curve) pkparse tests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Słowik --- tests/suites/test_suite_pkparse.data | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data index 30bee6a004..69b4dbfd29 100644 --- a/tests/suites/test_suite_pkparse.data +++ b/tests/suites/test_suite_pkparse.data @@ -1192,11 +1192,11 @@ depends_on:PSA_WANT_ECC_SECP_R1_256 pk_parse_public_keyfile_ec:"../framework/data_files/ec_256_pub.der":0 Parse Public EC Key #4c (RFC 5480, secp256r1, explicit) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_256_pub.expl.pem":0 Parse Public EC Key #4d (RFC 5480, secp256r1, explicit, DER) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_256_pub.expl.der":0 Parse Public EC Key #5 (RFC 5480, secp384r1) @@ -1208,7 +1208,7 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_SEC pk_parse_public_keyfile_ec:"../framework/data_files/ec_384_pub.comp.pem":0 Parse Public EC Key #5b (RFC 5480, secp384r1, explicit) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_384_pub.expl.pem":0 Parse Public EC Key #6 (RFC 5480, secp521r1) @@ -1220,11 +1220,11 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_SEC pk_parse_public_keyfile_ec:"../framework/data_files/ec_521_pub.comp.pem":0 Parse Public EC Key #6b (RFC 5480, secp521r1, explicit) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_521_pub.expl.pem":0 Parse Public EC Key #6c (RFC 5480, secp521r1, explicit, DER) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_521_pub.expl.der":0 Parse Public EC Key #7 (RFC 5480, brainpoolP256r1) @@ -1236,7 +1236,7 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_BP2 pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp256_pub.comp.pem":0 Parse Public EC Key #7b (RFC 5480, brainpoolP256r1, explicit) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP256R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP256R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp256_pub.expl.pem":0 Parse Public EC Key #8 (RFC 5480, brainpoolP384r1) @@ -1248,7 +1248,7 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_BP3 pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp384_pub.comp.pem":0 Parse Public EC Key #8b (RFC 5480, brainpoolP384r1, explicit) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP384R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP384R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp384_pub.expl.pem":0 Parse Public EC Key #9 (RFC 5480, brainpoolP512r1) @@ -1260,11 +1260,11 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_EC_COMPRESSED:MBEDTLS_ECP_DP_BP5 pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp512_pub.comp.pem":0 Parse Public EC Key #9b (RFC 5480, brainpoolP512r1, explicit) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP512R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp512_pub.expl.pem":0 Parse Public EC Key #9c (RFC 5480, brainpoolP512r1, explicit, DER) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP512R1_ENABLED +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED pk_parse_public_keyfile_ec:"../framework/data_files/ec_bp512_pub.expl.der":0 Parse Public EC Key #10 (RFC 8410, DER, X25519) From d154ad83a7ed3d4f6b30239b37e0ce72a626d689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82owik?= Date: Thu, 5 Mar 2026 14:45:16 +0100 Subject: [PATCH 5/6] Remove internal functions from Changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Słowik --- ChangeLog.d/fix-pk_group_from_specified.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ChangeLog.d/fix-pk_group_from_specified.txt b/ChangeLog.d/fix-pk_group_from_specified.txt index acec74c398..116d3e52fc 100644 --- a/ChangeLog.d/fix-pk_group_from_specified.txt +++ b/ChangeLog.d/fix-pk_group_from_specified.txt @@ -1,6 +1,4 @@ Bugfix: - * Fix `pk_group_from_specified` self-referencing group generator G while loading G. - * Fix `pk_group_from_specified` not accounting for the a = p-3 internal representation. - * Fix `pk_parse_public_key` failing to load keys with explicit curve parameters. + * Fix `mbedtls_pk_parse_public_key` failing to load keys with explicit curve parameters. Fixes #4314 From 4c4fe7b047ca0078705571ca504076ee19da719f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82owik?= Date: Thu, 5 Mar 2026 15:09:55 +0100 Subject: [PATCH 6/6] Cleanup changelog entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Słowik --- ChangeLog.d/fix-pk_group_from_specified.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/fix-pk_group_from_specified.txt b/ChangeLog.d/fix-pk_group_from_specified.txt index 116d3e52fc..66d3f9ef04 100644 --- a/ChangeLog.d/fix-pk_group_from_specified.txt +++ b/ChangeLog.d/fix-pk_group_from_specified.txt @@ -1,4 +1,4 @@ Bugfix: - * Fix `mbedtls_pk_parse_public_key` failing to load keys with explicit curve parameters. + * Fix mbedtls_pk_parse_public_key failing to load keys with explicit curve parameters. Fixes #4314