From 13cf3eca5b717cd6af29439266d9cf8588018942 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Nov 2018 22:06:48 +0100 Subject: [PATCH 01/33] Fix typo in documentation --- include/mbedtls/ecp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 24017780d..065a4cc0b 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -482,7 +482,7 @@ void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ); * * \note After this function is called, domain parameters * for various ECP groups can be loaded through the - * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group() + * mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group() * functions. */ void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ); From 552563b7413097c66843bc49e671fc36f9df77ca Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Nov 2018 22:07:58 +0100 Subject: [PATCH 02/33] Add test case for ecdh_calc_secret Add a test case for doing an ECDH calculation by calling mbedtls_ecdh_get_params on both keys, then mbedtls_ecdh_calc_secret. --- tests/suites/test_suite_ecdh.data | 8 +++ tests/suites/test_suite_ecdh.function | 93 +++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data index fe24ed46a..f90d88da8 100644 --- a/tests/suites/test_suite_ecdh.data +++ b/tests/suites/test_suite_ecdh.data @@ -79,3 +79,11 @@ ecdh_restart:MBEDTLS_ECP_DP_SECP256R1:"C88F01F510D9AC3F70A292DAA2316DE544E9AAB8A ECDH exchange legacy context depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecdh_exchange_legacy:MBEDTLS_ECP_DP_SECP192R1 + +ECDH calc_secret: ours first, SECP256R1 (RFC 5903) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_SECP256R1:"c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0b283ab46476bee53":"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":0:"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de" + +ECDH calc_secret: theirs first, SECP256R1 (RFC 5903) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_SECP256R1:"c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0b283ab46476bee53":"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":1:"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de" diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function index 7db0ed16e..1a7372e56 100644 --- a/tests/suites/test_suite_ecdh.function +++ b/tests/suites/test_suite_ecdh.function @@ -1,5 +1,41 @@ /* BEGIN_HEADER */ #include "mbedtls/ecdh.h" + +static int load_public_key( int grp_id, data_t *point, + mbedtls_ecp_keypair *ecp ) +{ + int ok = 0; + TEST_ASSERT( mbedtls_ecp_group_load( &ecp->grp, grp_id ) == 0 ); + TEST_ASSERT( mbedtls_ecp_point_read_binary( &ecp->grp, + &ecp->Q, + point->x, + point->len ) == 0 ); + TEST_ASSERT( mbedtls_ecp_check_pubkey( &ecp->grp, + &ecp->Q ) == 0 ); + ok = 1; +exit: + return( ok ); +} + +static int load_private_key( int grp_id, data_t *private_key, + mbedtls_ecp_keypair *ecp, + rnd_pseudo_info *rnd_info ) +{ + int ok = 0; + TEST_ASSERT( mbedtls_ecp_group_load( &ecp->grp, grp_id ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_binary( &ecp->d, + private_key->x, + private_key->len ) == 0 ); + TEST_ASSERT( mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) == 0 ); + /* Calculate the public key from the private key. */ + TEST_ASSERT( mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, + &ecp->grp.G, + &rnd_pseudo_rand, rnd_info ) == 0 ); + ok = 1; +exit: + return( ok ); +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -464,3 +500,60 @@ exit: mbedtls_ecdh_free( &cli ); } /* END_CASE */ + +/* BEGIN_CASE */ +void ecdh_exchange_calc_secret( int grp_id, + data_t *our_private_key, + data_t *their_point, + int ours_first, + data_t *expected ) +{ + rnd_pseudo_info rnd_info; + mbedtls_ecp_keypair our_key; + mbedtls_ecp_keypair their_key; + mbedtls_ecdh_context ecdh; + unsigned char shared_secret[MBEDTLS_ECP_MAX_BYTES]; + size_t shared_secret_length = 0; + + memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) ); + mbedtls_ecdh_init( &ecdh ); + mbedtls_ecp_keypair_init( &our_key ); + mbedtls_ecp_keypair_init( &their_key ); + + if( ! load_private_key( grp_id, our_private_key, &our_key, &rnd_info ) ) + goto exit; + if( ! load_public_key( grp_id, their_point, &their_key ) ) + goto exit; + + /* Import the keys to the ECDH calculation. */ + if( ours_first ) + { + TEST_ASSERT( mbedtls_ecdh_get_params( + &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 ); + TEST_ASSERT( mbedtls_ecdh_get_params( + &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 ); + } + else + { + TEST_ASSERT( mbedtls_ecdh_get_params( + &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 ); + TEST_ASSERT( mbedtls_ecdh_get_params( + &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 ); + } + + /* Perform the ECDH calculation. */ + TEST_ASSERT( mbedtls_ecdh_calc_secret( + &ecdh, + &shared_secret_length, + shared_secret, sizeof( shared_secret ), + &rnd_pseudo_rand, &rnd_info ) == 0 ); + TEST_ASSERT( shared_secret_length == expected->len ); + TEST_ASSERT( memcmp( expected->x, shared_secret, + shared_secret_length ) == 0 ); + +exit: + mbedtls_ecdh_free( &ecdh ); + mbedtls_ecp_keypair_free( &our_key ); + mbedtls_ecp_keypair_free( &their_key ); +} +/* END_CASE */ From c4dff06f31396d51623f4d0b0baf945f4baefaa3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Nov 2018 22:09:29 +0100 Subject: [PATCH 03/33] Add test case for ecdh_get_params with mismatching group Add a test case for doing an ECDH calculation by calling mbedtls_ecdh_get_params on both keys, with keys belonging to different groups. This should fail, but currently passes. --- tests/suites/test_suite_ecdh.data | 8 +++++ tests/suites/test_suite_ecdh.function | 47 +++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data index f90d88da8..af25359d3 100644 --- a/tests/suites/test_suite_ecdh.data +++ b/tests/suites/test_suite_ecdh.data @@ -87,3 +87,11 @@ ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_SECP256R1:"c6ef9c5d78ae012a011164acb397 ECDH calc_secret: theirs first, SECP256R1 (RFC 5903) depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_SECP256R1:"c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0b283ab46476bee53":"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":1:"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de" + +ECDH get_params with mismatched groups: our BP256R1, their SECP256R1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_BP256R1_ENABLED +ecdh_exchange_get_params_fail:MBEDTLS_ECP_DP_BP256R1:"1234567812345678123456781234567812345678123456781234567812345678":MBEDTLS_ECP_DP_SECP256R1:"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":0:MBEDTLS_ERR_ECP_BAD_INPUT_DATA + +ECDH get_params with mismatched groups: their SECP256R1, our BP256R1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_BP256R1_ENABLED +ecdh_exchange_get_params_fail:MBEDTLS_ECP_DP_BP256R1:"1234567812345678123456781234567812345678123456781234567812345678":MBEDTLS_ECP_DP_SECP256R1:"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":1:MBEDTLS_ERR_ECP_BAD_INPUT_DATA diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function index 1a7372e56..1a33d8175 100644 --- a/tests/suites/test_suite_ecdh.function +++ b/tests/suites/test_suite_ecdh.function @@ -557,3 +557,50 @@ exit: mbedtls_ecp_keypair_free( &their_key ); } /* END_CASE */ + +/* BEGIN_CASE */ +void ecdh_exchange_get_params_fail( int our_grp_id, + data_t *our_private_key, + int their_grp_id, + data_t *their_point, + int ours_first, + int expected_ret ) +{ + rnd_pseudo_info rnd_info; + mbedtls_ecp_keypair our_key; + mbedtls_ecp_keypair their_key; + mbedtls_ecdh_context ecdh; + + memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) ); + mbedtls_ecdh_init( &ecdh ); + mbedtls_ecp_keypair_init( &our_key ); + mbedtls_ecp_keypair_init( &their_key ); + + if( ! load_private_key( our_grp_id, our_private_key, &our_key, &rnd_info ) ) + goto exit; + if( ! load_public_key( their_grp_id, their_point, &their_key ) ) + goto exit; + + if( ours_first ) + { + TEST_ASSERT( mbedtls_ecdh_get_params( + &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 ); + TEST_ASSERT( mbedtls_ecdh_get_params( + &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == + expected_ret ); + } + else + { + TEST_ASSERT( mbedtls_ecdh_get_params( + &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 ); + TEST_ASSERT( mbedtls_ecdh_get_params( + &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == + expected_ret ); + } + +exit: + mbedtls_ecdh_free( &ecdh ); + mbedtls_ecp_keypair_free( &our_key ); + mbedtls_ecp_keypair_free( &their_key ); +} +/* END_CASE */ From 0b1b71d712f570b387787b15a9e3cf2c6fe87fe8 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Nov 2018 22:10:59 +0100 Subject: [PATCH 04/33] Fix ecdh_get_params with mismatching group If mbedtls_ecdh_get_params is called with keys belonging to different groups, make it return an error the second time, rather than silently interpret the first key as being on the second curve. This makes the non-regression test added by the previous commit pass. --- library/ecdh.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/library/ecdh.c b/library/ecdh.c index da95c60da..204a2785f 100644 --- a/library/ecdh.c +++ b/library/ecdh.c @@ -442,8 +442,21 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS || side == MBEDTLS_ECDH_THEIRS ); - if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 ) - return( ret ); + if( ctx->grp.id == MBEDTLS_ECP_DP_NONE ) + { + /* This is the first call to get_params(). Set up the context + * for use with the group. */ + if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 ) + return( ret ); + } + else + { + /* This is not the first call to get_params(). Check that the + * current key's group is the same as the context's, which was set + * from the first key's group. */ + if( ctx->grp.id != key->grp.id ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + } #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) return( ecdh_get_params_internal( ctx, key, side ) ); From ccf8ba0e6d314a3cb509277dd6a825f8c3921b0e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Nov 2018 22:39:16 +0100 Subject: [PATCH 05/33] Add changelog entry for mbedtls_ecdh_get_params robustness --- ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 606f8f0b2..b4c8c47b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,14 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.x.x branch released xxxx-xx-xx +Security + * Make mbedtls_ecdh_get_params return an error if the second key + belongs to a different group from the first. Before, if an application + passed keys that belonged to different group, the first key's data was + interpreted according to the second group, which could lead to either + an error or a meaningless output from mbedtls_ecdh_get_params. In the + latter case, this could expose at most 5 bits of the private key. + Bugfix * Fix a compilation issue with mbedtls_ecp_restart_ctx not being defined when MBEDTLS_ECP_ALT is defined. Reported by jwhui. Fixes #2242. From 43f564f29d7665e278783ae8ae32161be1ac02db Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 22 Feb 2019 12:14:02 +0100 Subject: [PATCH 06/33] Define MBEDTLS_ECDH_LEGACY_CONTEXT in config.h Define MBEDTLS_ECDH_LEGACY_CONTEXT in config.h instead of hard-coding this in ecdh.h so that its absence can be tested. Document it as experimental so that we reserve the right to change it in the future. --- include/mbedtls/check_config.h | 5 +++++ include/mbedtls/config.h | 31 ++++++++++++++++++++++++++++++- include/mbedtls/ecdh.h | 12 ------------ library/version_features.c | 3 +++ 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 3d47899c7..d4e9e4e8c 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -124,6 +124,11 @@ #error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation" #endif +#if defined(MBEDTLS_ECP_RESTARTABLE) && \ + ! defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +#error "MBEDTLS_ECP_RESTARTABLE defined, but not MBEDTLS_ECDH_LEGACY_CONTEXT" +#endif + #if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) #error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" #endif diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index e6abf24d5..664fc68dc 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -740,10 +740,39 @@ * * \note This option only works with the default software implementation of * elliptic curve functionality. It is incompatible with - * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT + * and MBEDTLS_ECDH_LEGACY_CONTEXT. */ //#define MBEDTLS_ECP_RESTARTABLE +/** + * \def MBEDTLS_ECDH_LEGACY_CONTEXT + * + * Use a backward compatible ECDH context. + * + * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context + * defined in `ecdh.h`). For most applications, the choice of format makes + * no difference, since all library functions can work with either format, + * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. + + * The new format used when this option is disabled is smaller + * (56 bytes on a 32-bit platform). In future versions of the library, it + * will support alternative implementations of ECDH operations. + * The new format is incompatible with applications that access + * context fields directly and with restartable ECP operations. + * + * Define this macro if you enable MBEDTLS_ECP_RESTARTABLE or if you + * want to access ECDH context fields directly. Otherwise you should + * comment out this macro definition. + * + * This option has no effect if #MBEDTLS_ECDH_C is not enabled. + * + * \note This configuration option is experimental. Future versions of the + * library may modify the way the ECDH context layout is configured + * and may modify the layout of the new context type. + */ +#define MBEDTLS_ECDH_LEGACY_CONTEXT + /** * \def MBEDTLS_ECDSA_DETERMINISTIC * diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h index 4479a1d46..384c3dc07 100644 --- a/include/mbedtls/ecdh.h +++ b/include/mbedtls/ecdh.h @@ -42,18 +42,6 @@ #include "ecp.h" -/* - * Use a backward compatible ECDH context. - * - * This flag is always enabled for now and future versions might add a - * configuration option that conditionally undefines this flag. - * The configuration option in question may have a different name. - * - * Features undefining this flag, must have a warning in their description in - * config.h stating that the feature breaks backward compatibility. - */ -#define MBEDTLS_ECDH_LEGACY_CONTEXT - #ifdef __cplusplus extern "C" { #endif diff --git a/library/version_features.c b/library/version_features.c index 61094d4ed..bbc365b92 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -348,6 +348,9 @@ static const char *features[] = { #if defined(MBEDTLS_ECP_RESTARTABLE) "MBEDTLS_ECP_RESTARTABLE", #endif /* MBEDTLS_ECP_RESTARTABLE */ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + "MBEDTLS_ECDH_LEGACY_CONTEXT", +#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ #if defined(MBEDTLS_ECDSA_DETERMINISTIC) "MBEDTLS_ECDSA_DETERMINISTIC", #endif /* MBEDTLS_ECDSA_DETERMINISTIC */ From e023c804771d2dab1809155c54fc04f511aca55e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 22 Feb 2019 12:31:02 +0100 Subject: [PATCH 07/33] Test undefining MBEDTLS_ECDH_LEGACY_CONTEXT in all.sh Test that the library works with the new context format. --- tests/scripts/all.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 90f9632d9..2a860afba 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -675,6 +675,23 @@ component_test_rsa_no_crt () { if_build_succeeded tests/compat.sh -t RSA } +component_test_new_ecdh_context () { + msg "build: new ECDH context (ASan build)" # ~ 6 min + scripts/config.pl unset MBEDTLS_ECDH_LEGACY_CONTEXT + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . + make + + msg "test: new ECDH context - main suites (inc. selftests) (ASan build)" # ~ 50s + make test + + msg "test: new ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s + if_build_succeeded tests/ssl-opt.sh -f ECDH + + msg "test: new ECDH context - compat.sh with some ECDH ciphersuites (ASan build)" # ~ 3 min + # Exclude some symmetric ciphers that are redundant here to gain time. + if_build_succeeded tests/compat.sh -f ECDH -V NO -e 'ARCFOUR\|ARIA\|CAMELLIA\|CHACHA\|DES\|RC4' +} + component_test_small_ssl_out_content_len () { msg "build: small SSL_OUT_CONTENT_LEN (ASan build)" scripts/config.pl set MBEDTLS_SSL_IN_CONTENT_LEN 16384 From 3081629de472cd1ae2dcf772f4b837e80d1c05ad Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 22 Feb 2019 12:31:25 +0100 Subject: [PATCH 08/33] Fix mbedtls_ecdh_get_params with new ECDH context The new check for matching groups in mbedtls_ecdh_get_params only worked with legacy ECDH contexts. Make it work with the new context format. --- library/ecdh.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/library/ecdh.c b/library/ecdh.c index 204a2785f..c5726877d 100644 --- a/library/ecdh.c +++ b/library/ecdh.c @@ -49,6 +49,16 @@ typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; #endif +static mbedtls_ecp_group_id mbedtls_ecdh_grp_id( + const mbedtls_ecdh_context *ctx ) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return( ctx->grp.id ); +#else + return( ctx->grp_id ); +#endif +} + #if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) /* * Generate public key (restartable version) @@ -442,7 +452,7 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS || side == MBEDTLS_ECDH_THEIRS ); - if( ctx->grp.id == MBEDTLS_ECP_DP_NONE ) + if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE ) { /* This is the first call to get_params(). Set up the context * for use with the group. */ @@ -454,7 +464,7 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, /* This is not the first call to get_params(). Check that the * current key's group is the same as the context's, which was set * from the first key's group. */ - if( ctx->grp.id != key->grp.id ) + if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); } From a778a94b7d8e241920775ea44f43a07b8f319732 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 13 Feb 2019 10:28:28 +0000 Subject: [PATCH 09/33] Add little endian import to Bignum The function `mbedtls_mpi_read_binary()` expects big endian byte order, but we need to be able to read from little endian in some caseses. (For example when handling keys corresponding to Montgomery curves.) Used `echo xx | tac -rs .. | tr [a-z] [A-Z]` to transform the test data to little endian and `echo "ibase=16;xx" | bc` to convert to decimal. --- include/mbedtls/bignum.h | 20 ++++++++++++++++++-- library/bignum.c | 28 ++++++++++++++++++++++++++++ tests/suites/test_suite_mpi.data | 3 +++ tests/suites/test_suite_mpi.function | 19 +++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index a54c18e37..0727917c5 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -490,8 +490,24 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ); /** - * \brief Export an MPI into unsigned big endian binary data - * of fixed size. + * \brief Import X from unsigned binary data, little endian + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param buf The input buffer. This must be a readable buffer of length + * \p buflen Bytes. + * \param buflen The length of the input buffer \p p in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_read_binary_le( mbedtls_mpi *X, + const unsigned char *buf, size_t buflen ); + +/** + * \brief Export X into unsigned binary data, big endian. + * Always fills the whole buffer, which will start with zeros + * if the number is smaller. * * \param X The source MPI. This must point to an initialized MPI. * \param buf The output buffer. This must be a writable buffer of length diff --git a/library/bignum.c b/library/bignum.c index 87015af0c..d28d3beb7 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -813,6 +813,34 @@ static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs ) } } +/* + * Import X from unsigned binary data, little endian + */ +int mbedtls_mpi_read_binary_le( mbedtls_mpi *X, + const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t i; + size_t const limbs = CHARS_TO_LIMBS( buflen ); + + /* Ensure that target MPI has exactly the necessary number of limbs */ + if( X->n != limbs ) + { + mbedtls_mpi_free( X ); + mbedtls_mpi_init( X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); + + for( i = 0; i < buflen; i++ ) + X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3); + +cleanup: + + return( ret ); +} + /* * Import X from unsigned binary data, big endian */ diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data index 8b5f97d38..7ad7ef663 100644 --- a/tests/suites/test_suite_mpi.data +++ b/tests/suites/test_suite_mpi.data @@ -58,6 +58,9 @@ mpi_read_write_string:16:"-1":16:"":3:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL Base test mbedtls_mpi_read_binary #1 mbedtls_mpi_read_binary:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924" +Base test mbedtls_mpi_read_binary_le #1 +mbedtls_mpi_read_binary_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":10:"219946662473865722255717126709915431768051735954189829340600976826409773245337023925691629251672268961177825243440202069039100741562168093042339401187848509859789949044607421190014088260008793380554914226244485299326152319899746569" + Base test mbedtls_mpi_write_binary #1 mbedtls_mpi_write_binary:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":200:0 diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function index d1fa5a46c..0ec45f655 100644 --- a/tests/suites/test_suite_mpi.function +++ b/tests/suites/test_suite_mpi.function @@ -328,6 +328,25 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void mbedtls_mpi_read_binary_le( data_t * buf, int radix_A, char * input_A ) +{ + mbedtls_mpi X; + unsigned char str[1000]; + size_t len; + + mbedtls_mpi_init( &X ); + + + TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 ); + TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, (char *) str, sizeof( str ), &len ) == 0 ); + TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 ); + +exit: + mbedtls_mpi_free( &X ); +} +/* END_CASE */ + /* BEGIN_CASE */ void mbedtls_mpi_write_binary( int radix_X, char * input_X, data_t * input_A, int output_size, From 59b813c7bebc64c1b0780fb6ddb2fb668b1b3b52 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 13 Feb 2019 10:44:06 +0000 Subject: [PATCH 10/33] Add Montgomery points to ecp_point_read_binary The library is able to perform computations and cryptographic schemes on curves with x coordinate ladder representation. Here we add the capability to import such points. --- library/ecp.c | 51 ++++++++++++++++++++-------- tests/suites/test_suite_ecp.data | 12 +++++++ tests/suites/test_suite_ecp.function | 19 +++++++++-- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/library/ecp.c b/library/ecp.c index ecea5910e..c509c820c 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -788,7 +788,7 @@ cleanup: } /* - * Import a point from unsigned binary data (SEC1 2.3.4) + * Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748) */ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, @@ -803,24 +803,45 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, if( ilen < 1 ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - if( buf[0] == 0x00 ) - { - if( ilen == 1 ) - return( mbedtls_ecp_set_zero( pt ) ); - else - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - plen = mbedtls_mpi_size( &grp->P ); - if( buf[0] != 0x04 ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); +#if defined(ECP_MONTGOMERY) + if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + { + if( plen != ilen ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - if( ilen != 2 * plen + 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &pt->X, buf, plen ) ); + mbedtls_mpi_free( &pt->Y ); + + if( grp->id == MBEDTLS_ECP_DP_CURVE25519 ) + /* Set most significant bit to 0 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &pt->X, plen * 8 - 1, 0 ) ); + } +#endif +#if defined(ECP_SHORTWEIERSTRASS) + if( ecp_get_type( grp ) != ECP_TYPE_MONTGOMERY ) + { + if( buf[0] == 0x00 ) + { + if( ilen == 1 ) + return( mbedtls_ecp_set_zero( pt ) ); + else + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + } + + if( buf[0] != 0x04 ) + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); + + if( ilen != 2 * plen + 1 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, + buf + 1 + plen, plen ) ); + } +#endif - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); cleanup: diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 30d5ec6f1..77fa724de 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -112,6 +112,18 @@ ECP read binary #6 (non-zero, OK) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_read_binary:MBEDTLS_ECP_DP_SECP192R1:"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":0 +ECP read binary #7 (Montgomery, OK) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":"6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085":"0":"1":0 + +ECP read binary #8 (Montgomery, masked first bit) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4efa":"7a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085":"0":"1":0 + +ECP read binary #9 (Montgomery, invalid length) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"20f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":"6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f020":"0":"1":MBEDTLS_ERR_ECP_BAD_INPUT_DATA + ECP tls read point #1 (zero, invalid length byte) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED mbedtls_ecp_tls_read_point:MBEDTLS_ECP_DP_SECP192R1:"0200":"01":"01":"00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 606ddd22a..58361db12 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -760,8 +760,23 @@ void ecp_read_binary( int id, data_t * buf, char * x, char * y, char * z, if( ret == 0 ) { TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.X, &X ) == 0 ); - TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Y, &Y ) == 0 ); - TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Z, &Z ) == 0 ); + /* + * At the time of writing, the following condition is equivalent with + * if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + * but has the advantage of not using internal symbols. + */ + if( grp.G.Y.p == NULL ) + { + TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, 0 ) == 0 ); + TEST_ASSERT( P.Y.p == NULL ); + TEST_ASSERT( mbedtls_mpi_cmp_int( &Z, 1 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_int( &P.Z, 1 ) == 0 ); + } + else + { + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Y, &Y ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Z, &Z ) == 0 ); + } } exit: From 171a7efd02c7eb79a69bcdaae945a4f16545d63b Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 15 Feb 2019 16:17:45 +0000 Subject: [PATCH 11/33] Add mbedtls_ecp_read_key The private keys used in ECDH differ in the case of Weierstrass and Montgomery curves. They have different constraints, the former is based on big endian, the latter little endian byte order. The fundamental approach is different too: - Weierstrass keys have to be in the right interval, otherwise they are rejected. - Any byte array of the right size is a valid Montgomery key and it needs to be masked before interpreting it as a number. Historically it was sufficient to use mbedtls_mpi_read_binary() to read private keys, but as a preparation to improve support for Montgomery curves we add mbedtls_ecp_read_key() to enable uniform treatment of EC keys. For the masking the `mbedtls_mpi_set_bit()` function is used. This is suboptimal but seems to provide the best trade-off at this time. Alternatives considered: - Making a copy of the input buffer (less efficient) - removing the `const` constraint from the input buffer (breaks the api and makes it less user friendly) - applying the mask directly to the limbs (violates the api between the modules and creates and unwanted dependency) --- include/mbedtls/ecp.h | 16 ++++++++ library/bignum.c | 10 +++++ library/ecp.c | 57 +++++++++++++++++++++++++++ tests/suites/test_suite_ecdh.function | 7 ++-- tests/suites/test_suite_ecp.data | 52 ++++++++++++++++++++++++ tests/suites/test_suite_ecp.function | 22 +++++++++++ 6 files changed, 160 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 065a4cc0b..7dee3e37e 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1093,6 +1093,22 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +/** + * \brief This function reads an ECP key. + * + * \param grp_id The ECP group identifier. + * \param key The destination key. + * \param buf The the buffer containing the binary representation of the + * key. (Big endian integer for Weierstrass curves, byte + * string for Montgomery curves.) + * \param buflen The length of the buffer in bytes. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + const unsigned char *buf, size_t buflen ); /** * \brief This function checks that the keypair objects * \p pub and \p prv have the same group and the diff --git a/library/bignum.c b/library/bignum.c index d28d3beb7..eb3264082 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -838,6 +838,11 @@ int mbedtls_mpi_read_binary_le( mbedtls_mpi *X, cleanup: + /* + * This function is also used to import keys. However, wiping the buffers + * upon failure is not necessary because failure only can happen before any + * input is copied. + */ return( ret ); } @@ -875,6 +880,11 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu cleanup: + /* + * This function is also used to import keys. However, wiping the buffers + * upon failure is not necessary because failure only can happen before any + * input is copied. + */ return( ret ); } diff --git a/library/ecp.c b/library/ecp.c index c509c820c..49f35afd5 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -2830,6 +2830,63 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); } +#define ECP_CURVE255_KEY_SIZE 32 +/* + * Read a private key. + */ +int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + const unsigned char *buf, size_t buflen ) +{ + int ret = 0; + + if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) + return( ret ); + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + /* + * If it is Curve25519 curve then mask the key as mandated by RFC7748 + */ + if( grp_id == MBEDTLS_ECP_DP_CURVE25519 ) + { + if( buflen != ECP_CURVE255_KEY_SIZE ) + return MBEDTLS_ERR_ECP_INVALID_KEY; + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) ); + + /* Set the three least significant bits to 0 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) ); + + /* Set the most significant bit to 0 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, + ECP_CURVE255_KEY_SIZE * 8 - 1, + 0 ) ); + + /* Set the second most significant bit to 1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, + ECP_CURVE255_KEY_SIZE * 8 - 2, + 1 ) ); + } + +#endif +#if defined(ECP_SHORTWEIERSTRASS) + if( ecp_get_type( &key->grp ) != ECP_TYPE_MONTGOMERY ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( &key->grp, &key->d ) ); + } + +#endif +cleanup: + + if( ret != 0 ) + mbedtls_mpi_free( &key->d ); + + return( ret ); +} + /* * Check a public-private key pair */ diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function index 1a33d8175..d6bed7f4c 100644 --- a/tests/suites/test_suite_ecdh.function +++ b/tests/suites/test_suite_ecdh.function @@ -22,10 +22,9 @@ static int load_private_key( int grp_id, data_t *private_key, rnd_pseudo_info *rnd_info ) { int ok = 0; - TEST_ASSERT( mbedtls_ecp_group_load( &ecp->grp, grp_id ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_binary( &ecp->d, - private_key->x, - private_key->len ) == 0 ); + TEST_ASSERT( mbedtls_ecp_read_key( grp_id, ecp, + private_key->x, + private_key->len ) == 0 ); TEST_ASSERT( mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) == 0 ); /* Calculate the public key from the private key. */ TEST_ASSERT( mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 77fa724de..1933d3fc2 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -256,6 +256,58 @@ ECP gen keypair wrapper depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED mbedtls_ecp_gen_key:MBEDTLS_ECP_DP_SECP192R1 +ECP read key #1 (short weierstrass, too small) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"00":MBEDTLS_ERR_ECP_INVALID_KEY + +ECP read key #2 (short weierstrass, smallest) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"01":0 + +ECP read key #3 (short weierstrass, biggest) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830":0 + +ECP read key #4 (short weierstrass, too big) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831":MBEDTLS_ERR_ECP_INVALID_KEY + +ECP read key #5 (montgomery, too big) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"000000000000000000000000000000000000000000000000000000000000000C":0 + +ECP read key #6 (montgomery, not big enough) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":0 + +ECP read key #7 (montgomery, msb OK) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000004":0 + +ECP read key #8 (montgomery, bit 0 set) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"1000000000000000000000000000000000000000000000000000000000000000":0 + +ECP read key #9 (montgomery, bit 1 set) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"2000000000000000000000000000000000000000000000000000000000000004":0 + +ECP read key #10 (montgomery, bit 2 set) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"4000000000000000000000000000000000000000000000000000000000000004":0 + +ECP read key #11 (montgomery, OK) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7":0 + +ECP read key #12 (montgomery, too long) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"00000000000000000000000000000000000000000000000000000000000000000C":MBEDTLS_ERR_ECP_INVALID_KEY + +ECP read key #13 (montgomery, not long enough) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":MBEDTLS_ERR_ECP_INVALID_KEY + ECP mod p192 small (more than 192 bits, less limbs than 2 * 192 bits) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_fast_mod:MBEDTLS_ECP_DP_SECP192R1:"0100000000000103010000000000010201000000000001010100000000000100" diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 58361db12..f1f96a1f2 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1021,6 +1021,28 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void mbedtls_ecp_read_key( int grp_id, data_t* in_key, int expected ) +{ + int ret = 0; + mbedtls_ecp_keypair key; + + mbedtls_ecp_keypair_init( &key ); + + ret = mbedtls_ecp_read_key( grp_id, &key, in_key->x, in_key->len ); + TEST_ASSERT( ret == expected ); + + if( expected == 0 ) + { + ret = mbedtls_ecp_check_privkey( &key.grp, &key.d ); + TEST_ASSERT( ret == 0 ); + } + +exit: + mbedtls_ecp_keypair_free( &key ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void ecp_selftest( ) { From e344d0f6fc8fab4097e9340a5bd3dddcfa2475ab Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 19 Feb 2019 16:17:40 +0000 Subject: [PATCH 12/33] Add little endian export to Bignum The function `mbedtls_mpi_write_binary()` writes big endian byte order, but we need to be able to write little endian in some caseses. (For example when handling keys corresponding to Montgomery curves.) Used `echo xx | tac -rs ..` to transform the test data to little endian. --- include/mbedtls/bignum.h | 18 +++++++++++++ library/bignum.c | 39 ++++++++++++++++++++++++++++ tests/suites/test_suite_mpi.data | 9 +++++++ tests/suites/test_suite_mpi.function | 31 ++++++++++++++++++++++ 4 files changed, 97 insertions(+) diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index 0727917c5..c4d768658 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -522,6 +522,24 @@ int mbedtls_mpi_read_binary_le( mbedtls_mpi *X, int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen ); +/** + * \brief Export X into unsigned binary data, little endian. + * Always fills the whole buffer, which will end with zeros + * if the number is smaller. + * + * \param X The source MPI. This must point to an initialized MPI. + * \param buf The output buffer. This must be a writable buffer of length + * \p buflen Bytes. + * \param buflen The size of the output buffer \p buf in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't + * large enough to hold the value of \p X. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X, + unsigned char *buf, size_t buflen ); + /** * \brief Perform a left-shift on an MPI: X <<= count * diff --git a/library/bignum.c b/library/bignum.c index eb3264082..f0882db4b 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -888,6 +888,45 @@ cleanup: return( ret ); } +/* + * Export X into unsigned binary data, little endian + */ +int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X, + unsigned char *buf, size_t buflen ) +{ + size_t stored_bytes = X->n * ciL; + size_t bytes_to_copy; + size_t i; + + if( stored_bytes < buflen ) + { + bytes_to_copy = stored_bytes; + } + else + { + bytes_to_copy = buflen; + + /* The output buffer is smaller than the allocated size of X. + * However X may fit if its leading bytes are zero. */ + for( i = bytes_to_copy; i < stored_bytes; i++ ) + { + if( GET_BYTE( X, i ) != 0 ) + return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); + } + } + + for( i = 0; i < bytes_to_copy; i++ ) + buf[i] = GET_BYTE( X, i ); + + if( stored_bytes < buflen ) + { + /* Write trailing 0 bytes */ + memset( buf + stored_bytes, 0, buflen - stored_bytes ); + } + + return( 0 ); +} + /* * Export X into unsigned binary data, big endian */ diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data index 7ad7ef663..f2be14816 100644 --- a/tests/suites/test_suite_mpi.data +++ b/tests/suites/test_suite_mpi.data @@ -70,6 +70,15 @@ mbedtls_mpi_write_binary:16:"123123123123123123123123123":"012312312312312312312 Test mbedtls_mpi_write_binary #2 (Buffer too small) mbedtls_mpi_write_binary:16:"123123123123123123123123123":"23123123123123123123123123":13:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL +Base test mbedtls_mpi_write_binary_le #1 +mbedtls_mpi_write_binary_le:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":"24448b952fbbef93f89286ba330e62528b151eac265cc8ce3038519d09e148af89288e91f48b41acad55d9dc5e2b18097c106be4ce132721bf6359eaf403e7ff90623e8866ee5c192320418daa682f144adedf84f25de11f49d1fe009d374109":200:0 + +Test mbedtls_mpi_write_binary_le #1 (Buffer just fits) +mbedtls_mpi_write_binary_le:16:"123123123123123123123123123":"2331122331122331122331122301":14:0 + +Test mbedtls_mpi_write_binary_le #2 (Buffer too small) +mbedtls_mpi_write_binary_le:16:"123123123123123123123123123":"23311223311223311223311223":13:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL + Base test mbedtls_mpi_read_file #1 mbedtls_mpi_read_file:10:"data_files/mpi_10":"01f55332c3a48b910f9942f6c914e58bef37a47ee45cb164a5b6b8d1006bf59a059c21449939ebebfdf517d2e1dbac88010d7b1f141e997bd6801ddaec9d05910f4f2de2b2c4d714e2c14a72fc7f17aa428d59c531627f09":0 diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function index 0ec45f655..5358379f0 100644 --- a/tests/suites/test_suite_mpi.function +++ b/tests/suites/test_suite_mpi.function @@ -378,6 +378,37 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void mbedtls_mpi_write_binary_le( int radix_X, char * input_X, + data_t * input_A, int output_size, + int result ) +{ + mbedtls_mpi X; + unsigned char buf[1000]; + size_t buflen; + + memset( buf, 0x00, 1000 ); + + mbedtls_mpi_init( &X ); + + TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 ); + + buflen = mbedtls_mpi_size( &X ); + if( buflen > (size_t) output_size ) + buflen = (size_t) output_size; + + TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result ); + if( result == 0) + { + + TEST_ASSERT( hexcmp( buf, input_A->x, buflen, input_A->len ) == 0 ); + } + +exit: + mbedtls_mpi_free( &X ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ void mbedtls_mpi_read_file( int radix_X, char * input_file, data_t * input_A, int result ) From ab0f71a22ae8b73e32b909f52f923b5114b5540a Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 20 Feb 2019 10:48:49 +0000 Subject: [PATCH 13/33] ECDH: Add test vectors for Curve25519 The test vectors added are published in RFC 7748. --- library/ecdh.c | 4 ++++ tests/suites/test_suite_ecdh.data | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/library/ecdh.c b/library/ecdh.c index c5726877d..30c5f9f7f 100644 --- a/library/ecdh.c +++ b/library/ecdh.c @@ -637,6 +637,10 @@ static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx, return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); + + if( ctx->grp.id == MBEDTLS_ECP_DP_CURVE25519 ) + return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen ); + return mbedtls_mpi_write_binary( &ctx->z, buf, *olen ); } diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data index af25359d3..fb4a232fc 100644 --- a/tests/suites/test_suite_ecdh.data +++ b/tests/suites/test_suite_ecdh.data @@ -88,6 +88,18 @@ ECDH calc_secret: theirs first, SECP256R1 (RFC 5903) depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_SECP256R1:"c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0b283ab46476bee53":"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":1:"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de" +ecdh calc_secret: ours first (Alice), curve25519 (rfc 7748) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_CURVE25519:"77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a":"de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f":0:"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" + +ecdh calc_secret: theirs first (Alice), curve25519 (rfc 7748) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_CURVE25519:"77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a":"de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f":1:"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" + +ecdh calc_secret: ours first (Bob), curve25519 (rfc 7748) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_CURVE25519:"5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb":"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":0:"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" + ECDH get_params with mismatched groups: our BP256R1, their SECP256R1 depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_BP256R1_ENABLED ecdh_exchange_get_params_fail:MBEDTLS_ECP_DP_BP256R1:"1234567812345678123456781234567812345678123456781234567812345678":MBEDTLS_ECP_DP_SECP256R1:"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":0:MBEDTLS_ERR_ECP_BAD_INPUT_DATA From 7caf8e452fe3ae80e19a46767af8a17db5c7466e Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 20 Feb 2019 12:00:22 +0000 Subject: [PATCH 14/33] Add Montgomery points to ecp_point_write_binary The library is able to perform computations and cryptographic schemes on curves with x coordinate ladder representation. Here we add the capability to export such points. --- library/ecp.c | 71 +++++++++++++++++++------------- tests/suites/test_suite_ecp.data | 8 ++++ 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/library/ecp.c b/library/ecp.c index 49f35afd5..66cf58ee7 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -729,7 +729,7 @@ cleanup: } /* - * Export a point into unsigned binary data (SEC1 2.3.3) + * Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748) */ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, @@ -745,43 +745,58 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || format == MBEDTLS_ECP_PF_COMPRESSED ); - /* - * Common case: P == 0 - */ - if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) - { - if( buflen < 1 ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - buf[0] = 0x00; - *olen = 1; - - return( 0 ); - } - plen = mbedtls_mpi_size( &grp->P ); - if( format == MBEDTLS_ECP_PF_UNCOMPRESSED ) +#if defined(ECP_MONTGOMERY) + if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) { - *olen = 2 * plen + 1; - + *olen = plen; if( buflen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - buf[0] = 0x04; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &P->X, buf, plen ) ); } - else if( format == MBEDTLS_ECP_PF_COMPRESSED ) +#endif +#if defined(ECP_SHORTWEIERSTRASS) + if( ecp_get_type( grp ) != ECP_TYPE_MONTGOMERY ) { - *olen = plen + 1; + /* + * Common case: P == 0 + */ + if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) + { + if( buflen < 1 ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - if( buflen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + buf[0] = 0x00; + *olen = 1; - buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); + return( 0 ); + } + + if( format == MBEDTLS_ECP_PF_UNCOMPRESSED ) + { + *olen = 2 * plen + 1; + + if( buflen < *olen ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x04; + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); + } + else if( format == MBEDTLS_ECP_PF_COMPRESSED ) + { + *olen = plen + 1; + + if( buflen < *olen ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); + } } +#endif cleanup: return( ret ); diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 1933d3fc2..ffa526db8 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -88,6 +88,14 @@ ECP write binary #9 (odd, compressed, buffer just fits) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_write_binary:MBEDTLS_ECP_DP_SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"93112b28345b7d1d7799611e49bea9d8290cb2d7afe1f9f3":"01":MBEDTLS_ECP_PF_COMPRESSED:"0348d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":25:0 +ECP write binary #10 (Montgomery, buffer just fits) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_binary:MBEDTLS_ECP_DP_CURVE25519:"11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff":"0":"1":MBEDTLS_ECP_PF_COMPRESSED:"ffeeddccbbaa00998877665544332211ffeeddccbbaa00998877665544332211":32:0 + +ECP write binary #11 (Montgomery, buffer too small) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_binary:MBEDTLS_ECP_DP_CURVE25519:"11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff":"0":"1":MBEDTLS_ECP_PF_COMPRESSED:"ffeeddccbbaa00998877665544332211ffeeddccbbaa00998877665544332211":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + ECP read binary #1 (zero, invalid ilen) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_read_binary:MBEDTLS_ECP_DP_SECP192R1:"0000":"01":"01":"00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA From ffbd7e8ff328e41ccea11ac48c096d4feac4f90c Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 25 Feb 2019 11:35:20 +0000 Subject: [PATCH 15/33] Improve mbedtls_ecp_point_read_binary tests Renamed the tests because they are explicitly testing Curve25519 and nothing else. Improved test coverage, test documentation and extended in-code documentation with a specific reference to the standard as well. --- library/ecp.c | 2 +- tests/suites/test_suite_ecp.data | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/library/ecp.c b/library/ecp.c index 66cf58ee7..8d0f49ae3 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -830,7 +830,7 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_mpi_free( &pt->Y ); if( grp->id == MBEDTLS_ECP_DP_CURVE25519 ) - /* Set most significant bit to 0 */ + /* Set most significant bit to 0 as prescribed in RFC7748 §5 */ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &pt->X, plen * 8 - 1, 0 ) ); } #endif diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index ffa526db8..87e863d5c 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -120,18 +120,30 @@ ECP read binary #6 (non-zero, OK) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_read_binary:MBEDTLS_ECP_DP_SECP192R1:"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":0 -ECP read binary #7 (Montgomery, OK) +ECP read binary #7 (Curve25519, OK) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":"6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085":"0":"1":0 -ECP read binary #8 (Montgomery, masked first bit) +ECP read binary #8 (Curve25519, masked first bit) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4efa":"7a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085":"0":"1":0 -ECP read binary #9 (Montgomery, invalid length) +ECP read binary #9 (Curve25519, too short) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"20f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":"6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f020":"0":"1":MBEDTLS_ERR_ECP_BAD_INPUT_DATA +ECP read binary #10 (Curve25519, non-canonical) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"0":"1":0 + +ECP read binary #11 (Curve25519, masked non-canonical) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"0":"1":0 + +ECP read binary #12 (Curve25519, too long) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a00":"6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085":"0":"1":MBEDTLS_ERR_ECP_BAD_INPUT_DATA + ECP tls read point #1 (zero, invalid length byte) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED mbedtls_ecp_tls_read_point:MBEDTLS_ECP_DP_SECP192R1:"0200":"01":"01":"00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA From e5670f26632aa7563a6a7eb3daad79993f515968 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 25 Feb 2019 16:11:58 +0000 Subject: [PATCH 16/33] Remove unnecessary cast from ECP test --- tests/suites/test_suite_mpi.function | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function index 5358379f0..67894e654 100644 --- a/tests/suites/test_suite_mpi.function +++ b/tests/suites/test_suite_mpi.function @@ -313,14 +313,14 @@ exit: void mbedtls_mpi_read_binary( data_t * buf, int radix_A, char * input_A ) { mbedtls_mpi X; - unsigned char str[1000]; + char str[1000]; size_t len; mbedtls_mpi_init( &X ); TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 ); - TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, (char *) str, sizeof( str ), &len ) == 0 ); + TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 ); TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 ); exit: @@ -332,14 +332,14 @@ exit: void mbedtls_mpi_read_binary_le( data_t * buf, int radix_A, char * input_A ) { mbedtls_mpi X; - unsigned char str[1000]; + char str[1000]; size_t len; mbedtls_mpi_init( &X ); TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 ); - TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, (char *) str, sizeof( str ), &len ) == 0 ); + TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 ); TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 ); exit: From 7780096f3b927b11c13e08891b5debd46c3cae84 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 25 Feb 2019 16:32:08 +0000 Subject: [PATCH 17/33] Fix typo in ECP module --- library/ecp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/ecp.c b/library/ecp.c index 8d0f49ae3..f27560566 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -2845,7 +2845,7 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); } -#define ECP_CURVE255_KEY_SIZE 32 +#define ECP_CURVE25519_KEY_SIZE 32 /* * Read a private key. */ @@ -2863,7 +2863,7 @@ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, */ if( grp_id == MBEDTLS_ECP_DP_CURVE25519 ) { - if( buflen != ECP_CURVE255_KEY_SIZE ) + if( buflen != ECP_CURVE25519_KEY_SIZE ) return MBEDTLS_ERR_ECP_INVALID_KEY; MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) ); @@ -2875,12 +2875,12 @@ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, /* Set the most significant bit to 0 */ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, - ECP_CURVE255_KEY_SIZE * 8 - 1, + ECP_CURVE25519_KEY_SIZE * 8 - 1, 0 ) ); /* Set the second most significant bit to 1 */ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, - ECP_CURVE255_KEY_SIZE * 8 - 2, + ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 ) ); } From b65853c6b638f2fb1069b4ae74ab9bf8253bfd0f Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 25 Feb 2019 16:33:28 +0000 Subject: [PATCH 18/33] Improve documentation of mbedtls_ecp_read_key --- include/mbedtls/ecp.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 7dee3e37e..ba3be207a 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1094,7 +1094,7 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, void *p_rng ); /** - * \brief This function reads an ECP key. + * \brief This function reads an elliptic curve private key. * * \param grp_id The ECP group identifier. * \param key The destination key. @@ -1104,8 +1104,10 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, * \param buflen The length of the buffer in bytes. * * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is + * invalid. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on different kinds of failure. */ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, const unsigned char *buf, size_t buflen ); From 28eb06df16d2205cfc6f49015e6786110b34c8ce Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 26 Feb 2019 10:53:34 +0000 Subject: [PATCH 19/33] ECP: Catch unsupported import/export mbedtls_ecp_read_key() module returned without an error even when importing keys corresponding to the requested group was not implemented. We change this and return an error when the requested group is not supported and make the remaining import/export functions more robust. --- include/mbedtls/ecp.h | 18 ++++++--- library/ecp.c | 67 +++++++++++++++++++------------- tests/suites/test_suite_ecp.data | 4 ++ 3 files changed, 57 insertions(+), 32 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index ba3be207a..384286edb 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -626,6 +626,9 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, * \param P The point to export. This must be initialized. * \param format The point format. This must be either * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. + * (For groups without these formats, this parameter is + * ignored. But it still has to be either of the above + * values.) * \param olen The address at which to store the length of * the output in Bytes. This must not be \c NULL. * \param buf The output buffer. This must be a writable buffer @@ -635,11 +638,14 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, * \return \c 0 on success. * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer * is too small to hold the point. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format + * or the export for the given group is not implemented. * \return Another negative error code on other kinds of failure. */ -int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, - int format, size_t *olen, - unsigned char *buf, size_t buflen ); +int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen ); /** * \brief This function imports a point from unsigned binary data. @@ -660,8 +666,8 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ * \return \c 0 on success. * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format - * is not implemented. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the import for the + * given group is not implemented. */ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, @@ -1107,6 +1113,8 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, * \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is * invalid. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for + * the group is not implemented. * \return Another negative error code on different kinds of failure. */ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, diff --git a/library/ecp.c b/library/ecp.c index f27560566..c918c95dc 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -736,7 +736,7 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, int format, size_t *olen, unsigned char *buf, size_t buflen ) { - int ret = 0; + int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; size_t plen; ECP_VALIDATE_RET( grp != NULL ); ECP_VALIDATE_RET( P != NULL ); @@ -758,7 +758,7 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, } #endif #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) != ECP_TYPE_MONTGOMERY ) + if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) { /* * Common case: P == 0 @@ -809,7 +809,7 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, const unsigned char *buf, size_t ilen ) { - int ret; + int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; size_t plen; ECP_VALIDATE_RET( grp != NULL ); ECP_VALIDATE_RET( pt != NULL ); @@ -832,10 +832,12 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, if( grp->id == MBEDTLS_ECP_DP_CURVE25519 ) /* Set most significant bit to 0 as prescribed in RFC7748 §5 */ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &pt->X, plen * 8 - 1, 0 ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); } #endif #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) != ECP_TYPE_MONTGOMERY ) + if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) { if( buf[0] == 0x00 ) { @@ -854,11 +856,10 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); } #endif - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); - cleanup: return( ret ); } @@ -2854,39 +2855,51 @@ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, { int ret = 0; + ECP_VALIDATE_RET( key != NULL ); + ECP_VALIDATE_RET( buf != NULL ); + if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) return( ret ); -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - /* - * If it is Curve25519 curve then mask the key as mandated by RFC7748 - */ - if( grp_id == MBEDTLS_ECP_DP_CURVE25519 ) + ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + +#if defined(ECP_MONTGOMERY) + if( ecp_get_type( &key->grp ) == ECP_TYPE_MONTGOMERY ) { - if( buflen != ECP_CURVE25519_KEY_SIZE ) - return MBEDTLS_ERR_ECP_INVALID_KEY; + /* + * If it is Curve25519 curve then mask the key as mandated by RFC7748 + */ + if( grp_id == MBEDTLS_ECP_DP_CURVE25519 ) + { + if( buflen != ECP_CURVE25519_KEY_SIZE ) + return MBEDTLS_ERR_ECP_INVALID_KEY; - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) ); - /* Set the three least significant bits to 0 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) ); + /* Set the three least significant bits to 0 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) ); - /* Set the most significant bit to 0 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, - ECP_CURVE25519_KEY_SIZE * 8 - 1, - 0 ) ); + /* Set the most significant bit to 0 */ + MBEDTLS_MPI_CHK( + mbedtls_mpi_set_bit( &key->d, + ECP_CURVE25519_KEY_SIZE * 8 - 1, 0 ) + ); - /* Set the second most significant bit to 1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, - ECP_CURVE25519_KEY_SIZE * 8 - 2, - 1 ) ); + /* Set the second most significant bit to 1 */ + MBEDTLS_MPI_CHK( + mbedtls_mpi_set_bit( &key->d, + ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 ) + ); + } + else + ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; } #endif #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( &key->grp ) != ECP_TYPE_MONTGOMERY ) + if( ecp_get_type( &key->grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) { MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) ); diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 87e863d5c..473193cfe 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -328,6 +328,10 @@ ECP read key #13 (montgomery, not long enough) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":MBEDTLS_ERR_ECP_INVALID_KEY +ECP read key #14 (Curve448, not supported) +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE448:"FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE + ECP mod p192 small (more than 192 bits, less limbs than 2 * 192 bits) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_fast_mod:MBEDTLS_ECP_DP_SECP192R1:"0100000000000103010000000000010201000000000001010100000000000100" From 4ffdbe0979c4d9718479e569058289b35fc30e68 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 26 Feb 2019 12:03:02 +0000 Subject: [PATCH 20/33] Add more tests for ecp_read_key --- tests/suites/test_suite_ecp.data | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 473193cfe..54fff6d8c 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -329,9 +329,15 @@ depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":MBEDTLS_ERR_ECP_INVALID_KEY ECP read key #14 (Curve448, not supported) -depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE448:"FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE +ECP read key #15 (Curve25519, not supported) +depends_on:!MBEDTLS_ECP_DP_CURVE25519_ENABLED +mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE + +ECP read key #15 (invalid curve) +mbedtls_ecp_read_key:INT_MAX:"8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE + ECP mod p192 small (more than 192 bits, less limbs than 2 * 192 bits) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_fast_mod:MBEDTLS_ECP_DP_SECP192R1:"0100000000000103010000000000010201000000000001010100000000000100" From df9295b7ecb0184f59ca3a848c2b261920d67205 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 26 Feb 2019 12:36:52 +0000 Subject: [PATCH 21/33] Make ecp_get_type public The ecp_get_type function comes handy in higher level modules and tests as well. It is not inline anymore, to enable alternative implementations to implement it for themselves. --- include/mbedtls/ecp.h | 15 +++++++++ library/ecp.c | 48 +++++++++++----------------- tests/suites/test_suite_ecp.function | 7 +--- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 384286edb..0b2504e1d 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -99,6 +99,16 @@ typedef enum */ #define MBEDTLS_ECP_DP_MAX 12 +/* + * Curve types + */ +typedef enum +{ + MBEDTLS_ECP_TYPE_NONE = 0, + MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ + MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ +} mbedtls_ecp_curve_type; + /** * Curve information, for use by other modules. */ @@ -417,6 +427,11 @@ void mbedtls_ecp_set_max_ops( unsigned max_ops ); int mbedtls_ecp_restart_is_enabled( void ); #endif /* MBEDTLS_ECP_RESTARTABLE */ +/* + * Get the type of a curve + */ +mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp ); + /** * \brief This function retrieves the information defined in * mbedtls_ecp_curve_info() for all supported curves in order diff --git a/library/ecp.c b/library/ecp.c index c918c95dc..69c432b76 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -363,16 +363,6 @@ int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, #define ECP_MONTGOMERY #endif -/* - * Curve types: internal for now, might be exposed later - */ -typedef enum -{ - ECP_TYPE_NONE = 0, - ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ - ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ -} ecp_curve_type; - /* * List of supported curves: * - internal ID @@ -522,15 +512,15 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name /* * Get the type of a curve */ -static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp ) +mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp ) { if( grp->G.X.p == NULL ) - return( ECP_TYPE_NONE ); + return( MBEDTLS_ECP_TYPE_NONE ); if( grp->G.Y.p == NULL ) - return( ECP_TYPE_MONTGOMERY ); + return( MBEDTLS_ECP_TYPE_MONTGOMERY ); else - return( ECP_TYPE_SHORT_WEIERSTRASS ); + return( MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ); } /* @@ -748,7 +738,7 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, plen = mbedtls_mpi_size( &grp->P ); #if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) { *olen = plen; if( buflen < *olen ) @@ -758,7 +748,7 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, } #endif #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) { /* * Common case: P == 0 @@ -821,7 +811,7 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, plen = mbedtls_mpi_size( &grp->P ); #if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) { if( plen != ilen ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); @@ -837,7 +827,7 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, } #endif #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) { if( buf[0] == 0x00 ) { @@ -2394,11 +2384,11 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; #if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); #endif #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) ); #endif @@ -2537,7 +2527,7 @@ int mbedtls_ecp_muladd_restartable( ECP_VALIDATE_RET( n != NULL ); ECP_VALIDATE_RET( Q != NULL ); - if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) + if( mbedtls_ecp_get_type( grp ) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); mbedtls_ecp_point_init( &mP ); @@ -2657,11 +2647,11 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, return( MBEDTLS_ERR_ECP_INVALID_KEY ); #if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) return( ecp_check_pubkey_mx( grp, pt ) ); #endif #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) return( ecp_check_pubkey_sw( grp, pt ) ); #endif return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); @@ -2677,7 +2667,7 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, ECP_VALIDATE_RET( d != NULL ); #if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) { /* see RFC 7748 sec. 5 para. 5 */ if( mbedtls_mpi_get_bit( d, 0 ) != 0 || @@ -2693,7 +2683,7 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, } #endif /* ECP_MONTGOMERY */ #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) { /* see SEC1 3.2 */ if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || @@ -2725,7 +2715,7 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, n_size = ( grp->nbits + 7 ) / 8; #if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) { /* [M225] page 5 */ size_t b; @@ -2753,7 +2743,7 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, #endif /* ECP_MONTGOMERY */ #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) { /* SEC1 3.2.1: Generate d such that 1 <= n < N */ int count = 0; @@ -2864,7 +2854,7 @@ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; #if defined(ECP_MONTGOMERY) - if( ecp_get_type( &key->grp ) == ECP_TYPE_MONTGOMERY ) + if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) { /* * If it is Curve25519 curve then mask the key as mandated by RFC7748 @@ -2899,7 +2889,7 @@ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, #endif #if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( &key->grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) { MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) ); diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index f1f96a1f2..ba271b1a5 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -760,12 +760,7 @@ void ecp_read_binary( int id, data_t * buf, char * x, char * y, char * z, if( ret == 0 ) { TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.X, &X ) == 0 ); - /* - * At the time of writing, the following condition is equivalent with - * if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) - * but has the advantage of not using internal symbols. - */ - if( grp.G.Y.p == NULL ) + if( mbedtls_ecp_get_type( &grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) { TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, 0 ) == 0 ); TEST_ASSERT( P.Y.p == NULL ); From bf42408528f5db2ba1d94e10dd34a784a52c5b2d Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 26 Feb 2019 13:53:55 +0000 Subject: [PATCH 22/33] Improve ECP test names --- tests/suites/test_suite_ecp.data | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 54fff6d8c..73d5315db 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -292,39 +292,39 @@ ECP read key #4 (short weierstrass, too big) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831":MBEDTLS_ERR_ECP_INVALID_KEY -ECP read key #5 (montgomery, too big) +ECP read key #5 (Curve25519, too big) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"000000000000000000000000000000000000000000000000000000000000000C":0 -ECP read key #6 (montgomery, not big enough) +ECP read key #6 (Curve25519, not big enough) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":0 -ECP read key #7 (montgomery, msb OK) +ECP read key #7 (Curve25519, msb OK) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000004":0 -ECP read key #8 (montgomery, bit 0 set) +ECP read key #8 (Curve25519, bit 0 set) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"1000000000000000000000000000000000000000000000000000000000000000":0 -ECP read key #9 (montgomery, bit 1 set) +ECP read key #9 (Curve25519, bit 1 set) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"2000000000000000000000000000000000000000000000000000000000000004":0 -ECP read key #10 (montgomery, bit 2 set) +ECP read key #10 (Curve25519, bit 2 set) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"4000000000000000000000000000000000000000000000000000000000000004":0 -ECP read key #11 (montgomery, OK) +ECP read key #11 (Curve25519, OK) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7":0 -ECP read key #12 (montgomery, too long) +ECP read key #12 (Curve25519, too long) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"00000000000000000000000000000000000000000000000000000000000000000C":MBEDTLS_ERR_ECP_INVALID_KEY -ECP read key #13 (montgomery, not long enough) +ECP read key #13 (Curve25519, not long enough) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":MBEDTLS_ERR_ECP_INVALID_KEY From 52ff8e938719eaeb33d6bf552afab2ea67e3e1ce Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 26 Feb 2019 13:56:04 +0000 Subject: [PATCH 23/33] Fix ECDH secret export for Mongomery curves We only switched to little endian for Curve25519, but all Montgomery curves require little endian byte order. --- library/ecdh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ecdh.c b/library/ecdh.c index 30c5f9f7f..eecae9131 100644 --- a/library/ecdh.c +++ b/library/ecdh.c @@ -638,7 +638,7 @@ static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx, *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); - if( ctx->grp.id == MBEDTLS_ECP_DP_CURVE25519 ) + if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen ); return mbedtls_mpi_write_binary( &ctx->z, buf, *olen ); From f607813f53532d2e6c8a3770887d5ffe4e302c72 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 26 Feb 2019 17:02:37 +0000 Subject: [PATCH 24/33] ECP: remove extra whitespaces --- library/ecp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ecp.c b/library/ecp.c index 69c432b76..c3c5ce540 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -742,7 +742,7 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, { *olen = plen; if( buflen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &P->X, buf, plen ) ); } From 54ba3eb7de94270efe26efa39f08d1b18d1bdf71 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 27 Feb 2019 14:47:10 +0000 Subject: [PATCH 25/33] ECP: Clarify test descriptions --- tests/suites/test_suite_ecp.data | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 73d5315db..86533665c 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -292,11 +292,11 @@ ECP read key #4 (short weierstrass, too big) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831":MBEDTLS_ERR_ECP_INVALID_KEY -ECP read key #5 (Curve25519, too big) +ECP read key #5 (Curve25519, most significant bit set) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"000000000000000000000000000000000000000000000000000000000000000C":0 -ECP read key #6 (Curve25519, not big enough) +ECP read key #6 (Curve25519, second most significant bit unset) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":0 From b78b300b2e10ac73cdaad7c95bd8ba4218852e57 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 29 Oct 2018 15:15:41 +0000 Subject: [PATCH 26/33] tests: Test crypto via the crypto submodule Test the crypto implementation via tests from the Mbed Crypto submodule instead of at the Mbed TLS top level. The version test is the only test that is tested from both TLS and Crypto, despite being entirely in libmbedcrypto. This is because the test data is code-gen'd from the version updating script and the version between Mbed TLS and Mbed Crypto don't necessarily always agree. The test data must come from the top level module, as only the top level module will have test data that matches the expected version. --- CMakeLists.txt | 3 + Makefile | 6 ++ tests/CMakeLists.txt | 136 ++++++++++++++++++++++--------------------- tests/Makefile | 72 +++++++++++++++++++++++ 4 files changed, 150 insertions(+), 67 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19ab4eb5f..ecfa40e03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,6 +195,9 @@ if(ENABLE_TESTING) enable_testing() add_subdirectory(tests) + if(USE_CRYPTO_SUBMODULE) + add_subdirectory(crypto/tests) + endif() # additional convenience targets for Unix only if(UNIX) diff --git a/Makefile b/Makefile index 87b5a0c0f..a5b8b610e 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,9 @@ lib: tests: lib $(MAKE) -C tests +ifdef USE_CRYPTO_SUBMODULE + $(MAKE) CRYPTO_INCLUDES:="-I../../include -I../include" -C crypto/tests +endif ifndef WINDOWS install: no_test @@ -103,6 +106,9 @@ endif check: lib tests $(MAKE) -C tests check +ifdef USE_CRYPTO_SUBMODULE + $(MAKE) CRYPTO_INCLUDES:="-I../../include -I../include" -C crypto/tests check +endif test: check diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a8e7523e5..ee8ff7909 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -60,76 +60,78 @@ if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX-") endif(MSVC) -add_test_suite(aes aes.ecb) -add_test_suite(aes aes.cbc) -add_test_suite(aes aes.cfb) -add_test_suite(aes aes.ofb) -add_test_suite(aes aes.rest) -add_test_suite(aes aes.xts) -add_test_suite(arc4) -add_test_suite(aria) -add_test_suite(asn1write) -add_test_suite(base64) -add_test_suite(blowfish) -add_test_suite(camellia) -add_test_suite(ccm) -add_test_suite(chacha20) -add_test_suite(chachapoly) -add_test_suite(cipher cipher.aes) -add_test_suite(cipher cipher.arc4) -add_test_suite(cipher cipher.blowfish) -add_test_suite(cipher cipher.camellia) -add_test_suite(cipher cipher.ccm) -add_test_suite(cipher cipher.chacha20) -add_test_suite(cipher cipher.chachapoly) -add_test_suite(cipher cipher.des) -add_test_suite(cipher cipher.gcm) -add_test_suite(cipher cipher.misc) -add_test_suite(cipher cipher.null) -add_test_suite(cipher cipher.padding) -add_test_suite(cmac) -add_test_suite(ctr_drbg) +if(NOT USE_CRYPTO_SUBMODULE) + add_test_suite(aes aes.ecb) + add_test_suite(aes aes.cbc) + add_test_suite(aes aes.cfb) + add_test_suite(aes aes.ofb) + add_test_suite(aes aes.rest) + add_test_suite(aes aes.xts) + add_test_suite(arc4) + add_test_suite(aria) + add_test_suite(asn1write) + add_test_suite(base64) + add_test_suite(blowfish) + add_test_suite(camellia) + add_test_suite(ccm) + add_test_suite(chacha20) + add_test_suite(chachapoly) + add_test_suite(cipher cipher.aes) + add_test_suite(cipher cipher.arc4) + add_test_suite(cipher cipher.blowfish) + add_test_suite(cipher cipher.camellia) + add_test_suite(cipher cipher.ccm) + add_test_suite(cipher cipher.chacha20) + add_test_suite(cipher cipher.chachapoly) + add_test_suite(cipher cipher.des) + add_test_suite(cipher cipher.gcm) + add_test_suite(cipher cipher.misc) + add_test_suite(cipher cipher.null) + add_test_suite(cipher cipher.padding) + add_test_suite(cmac) + add_test_suite(ctr_drbg) + add_test_suite(des) + add_test_suite(dhm) + add_test_suite(ecdh) + add_test_suite(ecdsa) + add_test_suite(ecjpake) + add_test_suite(ecp) + add_test_suite(entropy) + add_test_suite(error) + add_test_suite(gcm gcm.aes128_en) + add_test_suite(gcm gcm.aes192_en) + add_test_suite(gcm gcm.aes256_en) + add_test_suite(gcm gcm.aes128_de) + add_test_suite(gcm gcm.aes192_de) + add_test_suite(gcm gcm.aes256_de) + add_test_suite(gcm gcm.camellia) + add_test_suite(gcm gcm.misc) + add_test_suite(hkdf) + add_test_suite(hmac_drbg hmac_drbg.misc) + add_test_suite(hmac_drbg hmac_drbg.no_reseed) + add_test_suite(hmac_drbg hmac_drbg.nopr) + add_test_suite(hmac_drbg hmac_drbg.pr) + add_test_suite(md) + add_test_suite(mdx) + add_test_suite(memory_buffer_alloc) + add_test_suite(mpi) + add_test_suite(nist_kw) + add_test_suite(pem) + add_test_suite(pkcs1_v15) + add_test_suite(pkcs1_v21) + add_test_suite(pkcs5) + add_test_suite(pk) + add_test_suite(pkparse) + add_test_suite(pkwrite) + add_test_suite(poly1305) + add_test_suite(shax) + add_test_suite(timing) + add_test_suite(rsa) + add_test_suite(xtea) +endif() add_test_suite(debug) -add_test_suite(des) -add_test_suite(dhm) -add_test_suite(ecdh) -add_test_suite(ecdsa) -add_test_suite(ecjpake) -add_test_suite(ecp) -add_test_suite(entropy) -add_test_suite(error) -add_test_suite(gcm gcm.aes128_en) -add_test_suite(gcm gcm.aes192_en) -add_test_suite(gcm gcm.aes256_en) -add_test_suite(gcm gcm.aes128_de) -add_test_suite(gcm gcm.aes192_de) -add_test_suite(gcm gcm.aes256_de) -add_test_suite(gcm gcm.camellia) -add_test_suite(gcm gcm.misc) -add_test_suite(hkdf) -add_test_suite(hmac_drbg hmac_drbg.misc) -add_test_suite(hmac_drbg hmac_drbg.no_reseed) -add_test_suite(hmac_drbg hmac_drbg.nopr) -add_test_suite(hmac_drbg hmac_drbg.pr) -add_test_suite(md) -add_test_suite(mdx) -add_test_suite(memory_buffer_alloc) -add_test_suite(mpi) -add_test_suite(nist_kw) -add_test_suite(pem) -add_test_suite(pkcs1_v15) -add_test_suite(pkcs1_v21) -add_test_suite(pkcs5) -add_test_suite(pk) -add_test_suite(pkparse) -add_test_suite(pkwrite) -add_test_suite(poly1305) -add_test_suite(shax) add_test_suite(ssl) -add_test_suite(timing) -add_test_suite(rsa) add_test_suite(version) -add_test_suite(xtea) add_test_suite(x509parse) add_test_suite(x509write) diff --git a/tests/Makefile b/tests/Makefile index 598bed6bd..72c734324 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -66,6 +66,78 @@ endif # constructed by stripping path 'suites/' and extension .data. APPS = $(basename $(subst suites/,,$(wildcard suites/test_suite_*.data))) +ifdef USE_CRYPTO_SUBMODULE +APPS := $(filter-out \ + test_suite_aes.cbc \ + test_suite_aes.cfb \ + test_suite_aes.ecb \ + test_suite_aes.ofb \ + test_suite_aes.rest \ + test_suite_aes.xts \ + test_suite_arc4 \ + test_suite_aria \ + test_suite_asn1write \ + test_suite_base64 \ + test_suite_blowfish \ + test_suite_camellia \ + test_suite_ccm \ + test_suite_chacha20 \ + test_suite_chachapoly \ + test_suite_cipher.aes \ + test_suite_cipher.arc4 \ + test_suite_cipher.blowfish \ + test_suite_cipher.camellia \ + test_suite_cipher.ccm \ + test_suite_cipher.chacha20 \ + test_suite_cipher.chachapoly \ + test_suite_cipher.des \ + test_suite_cipher.gcm \ + test_suite_cipher.misc \ + test_suite_cipher.null \ + test_suite_cipher.padding \ + test_suite_cmac \ + test_suite_ctr_drbg \ + test_suite_des \ + test_suite_dhm \ + test_suite_ecdh \ + test_suite_ecdsa \ + test_suite_ecjpake \ + test_suite_ecp \ + test_suite_entropy \ + test_suite_error \ + test_suite_gcm.aes128_de \ + test_suite_gcm.aes128_en \ + test_suite_gcm.aes192_de \ + test_suite_gcm.aes192_en \ + test_suite_gcm.aes256_de \ + test_suite_gcm.aes256_en \ + test_suite_gcm.camellia \ + test_suite_gcm.misc \ + test_suite_hkdf \ + test_suite_hmac_drbg.misc \ + test_suite_hmac_drbg.nopr \ + test_suite_hmac_drbg.no_reseed \ + test_suite_hmac_drbg.pr \ + test_suite_md \ + test_suite_mdx \ + test_suite_memory_buffer_alloc \ + test_suite_mpi \ + test_suite_nist_kw \ + test_suite_pem \ + test_suite_pk \ + test_suite_pkcs1_v15 \ + test_suite_pkcs1_v21 \ + test_suite_pkcs5 \ + test_suite_pkparse \ + test_suite_pkwrite \ + test_suite_poly1305 \ + test_suite_rsa \ + test_suite_shax \ + test_suite_timing \ + test_suite_xtea \ + ,$(APPS)) +endif + # Construct executable name by adding OS specific suffix $(EXEXT). BINARIES := $(addsuffix $(EXEXT),$(APPS)) From c9391b02d5a2cff7c2e89742643454a6e695fe76 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Wed, 13 Mar 2019 11:37:06 +0000 Subject: [PATCH 27/33] Update crypto submodule to Mbed Crypto development Update the crypto submodule to the top of the Mbed Crypto development branch. This brings in a version of Mbed Crypto compatible with being tested using its tests (as it avoids adding duplicate and conflicting CMake jobs). --- crypto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto b/crypto index a78c958b1..a52c0593c 160000 --- a/crypto +++ b/crypto @@ -1 +1 @@ -Subproject commit a78c958b17d75ddf63d8dd17255b6379dcbf259f +Subproject commit a52c0593cceb54113d7cd9937b042fd395f55991 From 2184ef63ab66f842322c10205c0141918d6a4c83 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Wed, 13 Mar 2019 14:50:00 +0000 Subject: [PATCH 28/33] tests: Use globbing in test suite exclusion list Use e.g. test_suite_aes.% instead of listing out subsuites. This makes is less of a pain to add new subsuites. --- tests/Makefile | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 72c734324..e2fbff7a5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -68,12 +68,7 @@ APPS = $(basename $(subst suites/,,$(wildcard suites/test_suite_*.data))) ifdef USE_CRYPTO_SUBMODULE APPS := $(filter-out \ - test_suite_aes.cbc \ - test_suite_aes.cfb \ - test_suite_aes.ecb \ - test_suite_aes.ofb \ - test_suite_aes.rest \ - test_suite_aes.xts \ + test_suite_aes.% \ test_suite_arc4 \ test_suite_aria \ test_suite_asn1write \ @@ -83,18 +78,7 @@ APPS := $(filter-out \ test_suite_ccm \ test_suite_chacha20 \ test_suite_chachapoly \ - test_suite_cipher.aes \ - test_suite_cipher.arc4 \ - test_suite_cipher.blowfish \ - test_suite_cipher.camellia \ - test_suite_cipher.ccm \ - test_suite_cipher.chacha20 \ - test_suite_cipher.chachapoly \ - test_suite_cipher.des \ - test_suite_cipher.gcm \ - test_suite_cipher.misc \ - test_suite_cipher.null \ - test_suite_cipher.padding \ + test_suite_cipher.% \ test_suite_cmac \ test_suite_ctr_drbg \ test_suite_des \ @@ -105,19 +89,9 @@ APPS := $(filter-out \ test_suite_ecp \ test_suite_entropy \ test_suite_error \ - test_suite_gcm.aes128_de \ - test_suite_gcm.aes128_en \ - test_suite_gcm.aes192_de \ - test_suite_gcm.aes192_en \ - test_suite_gcm.aes256_de \ - test_suite_gcm.aes256_en \ - test_suite_gcm.camellia \ - test_suite_gcm.misc \ + test_suite_gcm.% \ test_suite_hkdf \ - test_suite_hmac_drbg.misc \ - test_suite_hmac_drbg.nopr \ - test_suite_hmac_drbg.no_reseed \ - test_suite_hmac_drbg.pr \ + test_suite_hmac_drbg.% \ test_suite_md \ test_suite_mdx \ test_suite_memory_buffer_alloc \ From 57f4d9e4fe31340880e39a383ed44f30dc6cde19 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 15 Mar 2019 16:14:19 +0000 Subject: [PATCH 29/33] Update crypto submodule to test with private headers Update the crypto submodule to the top of the Mbed Crypto development branch. This brings in a version of Mbed Crypto that enables building Mbed Crypto tests that depend on private headers, like 'psa_crypto_invasive.h'. This also requires updating our config.h to include new configuration options added to Mbed Crypto. MBEDTLS_PSA_ITS_FILE_C replaces MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C and MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C. MBEDTLS_PSA_INJECT_ENTROPY replaces MBEDTLS_PSA_HAS_ITS_IO. --- crypto | 2 +- include/mbedtls/check_config.h | 27 ++++++++++---------- include/mbedtls/config.h | 45 +++++++++++++--------------------- library/version_features.c | 15 +++++------- programs/ssl/query_config.c | 24 ++++++------------ scripts/config.pl | 10 +++----- 6 files changed, 49 insertions(+), 74 deletions(-) diff --git a/crypto b/crypto index a52c0593c..82b3b83d5 160000 --- a/crypto +++ b/crypto @@ -1 +1 @@ -Subproject commit a52c0593cceb54113d7cd9937b042fd395f55991 +Subproject commit 82b3b83d540ec9611277ca3e9b645b335f80846a diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 962d3db87..c1450dbda 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -525,26 +525,25 @@ #error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites" #endif -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) && defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) -#error "Only one of MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C or MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C can be defined" -#endif - #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ - !( defined(MBEDTLS_PSA_CRYPTO_C) && \ - ( defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) || \ - defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) ) ) + ! defined(MBEDTLS_PSA_CRYPTO_C) #error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) && \ - !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ - defined(MBEDTLS_FS_IO) ) -#error "MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C defined, but not all prerequisites" +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ + defined(MBEDTLS_ENTROPY_NV_SEED) ) +#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites" #endif -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) && \ - ! defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) -#error "MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C defined, but not all prerequisites" +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) +#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources" +#endif + +#if defined(MBEDTLS_PSA_ITS_FILE_C) && \ + !defined(MBEDTLS_FS_IO) +#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites" #endif #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 3a2fed528..31a305923 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1237,14 +1237,17 @@ //#define MBEDTLS_PSA_CRYPTO_SPM /** - * \def MBEDTLS_PSA_HAS_ITS_IO + * \def MBEDTLS_PSA_INJECT_ENTROPY * - * Enable the non-volatile secure storage usage. + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. * - * This is crucial on systems that do not have a HW TRNG support. + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED * */ -//#define MBEDTLS_PSA_HAS_ITS_IO +//#define MBEDTLS_PSA_INJECT_ENTROPY /** * \def MBEDTLS_RSA_NO_CRT @@ -2741,40 +2744,26 @@ * * Enable the Platform Security Architecture persistent key storage. * - * Module: library/psa_crypto_storage.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C and one of either - * MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C or MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - * (but not both) + * Module: crypto/library/psa_crypto_storage.c * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface */ //#define MBEDTLS_PSA_CRYPTO_STORAGE_C /** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C + * \def MBEDTLS_PSA_ITS_FILE_C * - * Enable persistent key storage over files for the - * Platform Security Architecture cryptography API. + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. * - * Module: library/psa_crypto_storage_file.c + * Module: crypto/library/psa_its_file.c * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_FS_IO + * Requires: MBEDTLS_FS_IO * */ -//#define MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C - -/** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - * - * Enable persistent key storage over PSA ITS for the - * Platform Security Architecture cryptography API. - * - * Module: library/psa_crypto_storage_its.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_HAS_ITS_IO - * - */ -//#define MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C +//#define MBEDTLS_PSA_ITS_FILE_C /** * \def MBEDTLS_RIPEMD160_C diff --git a/library/version_features.c b/library/version_features.c index 161788ca7..1be0e0fc9 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -429,9 +429,9 @@ static const char *features[] = { #if defined(MBEDTLS_PSA_CRYPTO_SPM) "MBEDTLS_PSA_CRYPTO_SPM", #endif /* MBEDTLS_PSA_CRYPTO_SPM */ -#if defined(MBEDTLS_PSA_HAS_ITS_IO) - "MBEDTLS_PSA_HAS_ITS_IO", -#endif /* MBEDTLS_PSA_HAS_ITS_IO */ +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) + "MBEDTLS_PSA_INJECT_ENTROPY", +#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ #if defined(MBEDTLS_RSA_NO_CRT) "MBEDTLS_RSA_NO_CRT", #endif /* MBEDTLS_RSA_NO_CRT */ @@ -708,12 +708,9 @@ static const char *features[] = { #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) "MBEDTLS_PSA_CRYPTO_STORAGE_C", #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) - "MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C", -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) - "MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C", -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C */ +#if defined(MBEDTLS_PSA_ITS_FILE_C) + "MBEDTLS_PSA_ITS_FILE_C", +#endif /* MBEDTLS_PSA_ITS_FILE_C */ #if defined(MBEDTLS_RIPEMD160_C) "MBEDTLS_RIPEMD160_C", #endif /* MBEDTLS_RIPEMD160_C */ diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index f2f7b46d6..f27267650 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -1186,13 +1186,13 @@ int query_config( const char *config ) } #endif /* MBEDTLS_PSA_CRYPTO_SPM */ -#if defined(MBEDTLS_PSA_HAS_ITS_IO) - if( strcmp( "MBEDTLS_PSA_HAS_ITS_IO", config ) == 0 ) +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) + if( strcmp( "MBEDTLS_PSA_INJECT_ENTROPY", config ) == 0 ) { - MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_HAS_ITS_IO ); + MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_INJECT_ENTROPY ); return( 0 ); } -#endif /* MBEDTLS_PSA_HAS_ITS_IO */ +#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ #if defined(MBEDTLS_RSA_NO_CRT) if( strcmp( "MBEDTLS_RSA_NO_CRT", config ) == 0 ) @@ -1930,21 +1930,13 @@ int query_config( const char *config ) } #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) - if( strcmp( "MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C", config ) == 0 ) +#if defined(MBEDTLS_PSA_ITS_FILE_C) + if( strcmp( "MBEDTLS_PSA_ITS_FILE_C", config ) == 0 ) { - MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C ); + MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_ITS_FILE_C ); return( 0 ); } -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C */ - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) - if( strcmp( "MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C", config ) == 0 ) - { - MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C ); - return( 0 ); - } -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C */ +#endif /* MBEDTLS_PSA_ITS_FILE_C */ #if defined(MBEDTLS_RIPEMD160_C) if( strcmp( "MBEDTLS_RIPEMD160_C", config ) == 0 ) diff --git a/scripts/config.pl b/scripts/config.pl index 84069d231..6300362fa 100755 --- a/scripts/config.pl +++ b/scripts/config.pl @@ -41,10 +41,9 @@ # MBEDTLS_USE_PSA_CRYPTO # - experimental, and more an alternative implementation than a feature # MBEDTLS_PSA_CRYPTO_STORAGE_C -# MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C -# MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C +# MBEDTLS_PSA_ITS_FILE_C # MBEDTLS_PSA_CRYPTO_SPM -# MBEDTLS_PSA_HAS_ITS_IO +# MBEDTLS_PSA_INJECT_ENTROPY # and any symbol beginning _ALT # @@ -109,10 +108,9 @@ MBEDTLS_NO_UDBL_DIVISION MBEDTLS_NO_64BIT_MULTIPLICATION MBEDTLS_USE_PSA_CRYPTO MBEDTLS_PSA_CRYPTO_STORAGE_C -MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C -MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C +MBEDTLS_PSA_ITS_FILE_C MBEDTLS_PSA_CRYPTO_SPM -MBEDTLS_PSA_HAS_ITS_IO +MBEDTLS_PSA_INJECT_ENTROPY _ALT\s*$ ); From 9714510736fb178bb194ccf5f9c38dc2ad8de7db Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 18 Mar 2019 16:31:21 +0000 Subject: [PATCH 30/33] all.sh: Generate seedfile for crypto submodule tests When running tests from the crypto submodule, generate and use a seedfile within the crypto/tests directory. --- tests/scripts/all.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 3f5d1d9f1..301dc52ee 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -406,6 +406,9 @@ pre_check_seedfile () { if [ ! -f "./tests/seedfile" ]; then dd if=/dev/urandom of=./tests/seedfile bs=32 count=1 fi + if [ ! -f "./crypto/tests/seedfile" ]; then + dd if=/dev/urandom of=./crypto/tests/seedfile bs=32 count=1 + fi } pre_setup_keep_going () { From 3f8d78411a26e833db18d9fbde0e2f0baeda87f0 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Tue, 19 Mar 2019 16:11:28 +0000 Subject: [PATCH 31/33] Update library version to 2.17.0 --- ChangeLog | 2 +- doxygen/input/doc_mainpage.h | 2 +- doxygen/mbedtls.doxyfile | 2 +- include/mbedtls/version.h | 10 +++++----- library/CMakeLists.txt | 6 +++--- tests/suites/test_suite_version.data | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index e2489bd37..adbf8a254 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ mbed TLS ChangeLog (Sorted per branch, date) -= mbed TLS 2.x.x branch released xxxx-xx-xx += mbed TLS 2.17.0 branch released 2019-03-19 Features * Add a new X.509 API call `mbedtls_x509_parse_der_nocopy()` diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h index d9177fb2d..4eff83692 100644 --- a/doxygen/input/doc_mainpage.h +++ b/doxygen/input/doc_mainpage.h @@ -24,7 +24,7 @@ */ /** - * @mainpage mbed TLS v0.0.0 source code documentation + * @mainpage mbed TLS v2.17.0 source code documentation * * This documentation describes the internal structure of mbed TLS. It was * automatically generated from specially formatted comment blocks in diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile index b0190e448..ce58d6b12 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8 # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. -PROJECT_NAME = "mbed TLS v0.0.0" +PROJECT_NAME = "mbed TLS v2.17.0" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h index 3f2e12ca5..79b42b26c 100644 --- a/include/mbedtls/version.h +++ b/include/mbedtls/version.h @@ -38,8 +38,8 @@ * The version number x.y.z is split into three parts. * Major, Minor, Patchlevel */ -#define MBEDTLS_VERSION_MAJOR 0 -#define MBEDTLS_VERSION_MINOR 0 +#define MBEDTLS_VERSION_MAJOR 2 +#define MBEDTLS_VERSION_MINOR 17 #define MBEDTLS_VERSION_PATCH 0 /** @@ -47,9 +47,9 @@ * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x00000000 -#define MBEDTLS_VERSION_STRING "0.0.0" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 0.0.0" +#define MBEDTLS_VERSION_NUMBER 0x02110000 +#define MBEDTLS_VERSION_STRING "2.17.0" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.17.0" #if defined(MBEDTLS_VERSION_C) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index bd58b8a14..fb43fd0a7 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -182,20 +182,20 @@ endif(USE_STATIC_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY) if(NOT USE_CRYPTO_SUBMODULE) add_library(mbedcrypto SHARED ${src_crypto}) - set_target_properties(mbedcrypto PROPERTIES VERSION 0.0.0 SOVERSION 3) + set_target_properties(mbedcrypto PROPERTIES VERSION 2.17.0 SOVERSION 3) target_link_libraries(mbedcrypto ${libs}) target_include_directories(mbedcrypto PUBLIC ${CMAKE_SOURCE_DIR}/include/) endif() add_library(mbedx509 SHARED ${src_x509}) - set_target_properties(mbedx509 PROPERTIES VERSION 0.0.0 SOVERSION 0) + set_target_properties(mbedx509 PROPERTIES VERSION 2.17.0 SOVERSION 0) target_link_libraries(mbedx509 ${libs} mbedcrypto) target_include_directories(mbedx509 PUBLIC ${CMAKE_SOURCE_DIR}/include/ PUBLIC ${CMAKE_SOURCE_DIR}/crypto/include/) add_library(mbedtls SHARED ${src_tls}) - set_target_properties(mbedtls PROPERTIES VERSION 0.0.0 SOVERSION 12) + set_target_properties(mbedtls PROPERTIES VERSION 2.17.0 SOVERSION 12) target_link_libraries(mbedtls ${libs} mbedx509) target_include_directories(mbedtls PUBLIC ${CMAKE_SOURCE_DIR}/include/ diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data index 7165f368a..a4575ab00 100644 --- a/tests/suites/test_suite_version.data +++ b/tests/suites/test_suite_version.data @@ -1,8 +1,8 @@ Check compiletime library version -check_compiletime_version:"0.0.0" +check_compiletime_version:"2.17.0" Check runtime library version -check_runtime_version:"0.0.0" +check_runtime_version:"2.17.0" Check for MBEDTLS_VERSION_C check_feature:"MBEDTLS_VERSION_C":0 From 11ee07191f955481d019e8fbdd5494240cfed546 Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Mon, 25 Mar 2019 18:22:52 +0200 Subject: [PATCH 32/33] Add certificate policy of type any policy id Add a function for getting the certificate policy. Currently only "Any Policy" is supported. --- include/mbedtls/oid.h | 15 ++++++++++++ library/oid.c | 9 ++++++++ tests/CMakeLists.txt | 1 + tests/suites/test_suite_oid.data | 8 +++++++ tests/suites/test_suite_oid.function | 34 ++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+) create mode 100644 tests/suites/test_suite_oid.data create mode 100644 tests/suites/test_suite_oid.function diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h index 65e626e11..342ef754e 100644 --- a/include/mbedtls/oid.h +++ b/include/mbedtls/oid.h @@ -167,6 +167,11 @@ #define MBEDTLS_OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */ #define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */ +/* + * Certificate policies + */ +#define MBEDTLS_OID_ANY_POLICY MBEDTLS_OID_CERTIFICATE_POLICIES "\x00" /**< anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } */ + /* * Netscape certificate extensions */ @@ -576,6 +581,16 @@ int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_ */ int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc ); +/** + * \brief Translate certificate policies OID into description + * + * \param oid OID to use + * \param desc place to store string pointer + * + * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND + */ +int mbedtls_oid_get_certificate_policies( const mbedtls_asn1_buf *oid, const char **desc ); + /** * \brief Translate md_type into hash algorithm OID * diff --git a/library/oid.c b/library/oid.c index 294bbd661..4e10f8a26 100644 --- a/library/oid.c +++ b/library/oid.c @@ -296,6 +296,15 @@ static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage) FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description) +static const mbedtls_oid_descriptor_t oid_certificate_policies[] = +{ + { ADD_LEN( MBEDTLS_OID_ANY_POLICY ), "anyPolicy", "Any Policy" }, + { NULL, 0, NULL, NULL }, +}; + +FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, certificate_policies, oid_certificate_policies) +FN_OID_GET_ATTR1(mbedtls_oid_get_certificate_policies, mbedtls_oid_descriptor_t, certificate_policies, const char *, description) + #if defined(MBEDTLS_MD_C) /* * For SignatureAlgorithmIdentifier diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a8e7523e5..1b7ea78ca 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -116,6 +116,7 @@ add_test_suite(mdx) add_test_suite(memory_buffer_alloc) add_test_suite(mpi) add_test_suite(nist_kw) +add_test_suite(oid) add_test_suite(pem) add_test_suite(pkcs1_v15) add_test_suite(pkcs1_v21) diff --git a/tests/suites/test_suite_oid.data b/tests/suites/test_suite_oid.data new file mode 100644 index 000000000..759a01038 --- /dev/null +++ b/tests/suites/test_suite_oid.data @@ -0,0 +1,8 @@ +OID get Any Policy certificate policy +oid_get_certificate_policies:"551D2000":"Any Policy" + +OID get certificate policy invalid oid +oid_get_certificate_policies:"5533445566":"" + +OID get certificate policy wrong oid - id-ce-authorityKeyIdentifier +oid_get_certificate_policies:"551D23":"" diff --git a/tests/suites/test_suite_oid.function b/tests/suites/test_suite_oid.function new file mode 100644 index 000000000..e95e48d06 --- /dev/null +++ b/tests/suites/test_suite_oid.function @@ -0,0 +1,34 @@ +/* BEGIN_HEADER */ +#include "mbedtls/oid.h" +#include "mbedtls/asn1.h" +#include "mbedtls/asn1write.h" +#include "string.h" +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_OID_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE depends_on:MBEDTLS_ASN1_WRITE_C*/ +void oid_get_certificate_policies( data_t * oid, char * result_str ) +{ + mbedtls_asn1_buf asn1_buf = { 0, 0, NULL }; + int ret; + const char *desc; + + asn1_buf.tag = MBEDTLS_ASN1_OID; + asn1_buf.p = oid->x; + asn1_buf.len = oid->len; + + ret = mbedtls_oid_get_certificate_policies( &asn1_buf, &desc ); + if( strlen( result_str ) == 0 ) + { + TEST_ASSERT( ret == MBEDTLS_ERR_OID_NOT_FOUND ); + } + else + { + TEST_ASSERT( strcmp( ( char* )desc, result_str ) == 0 ); + } +} +/* END_CASE */ From 3b11c8590e59ae2306f43a84d653c4d1ee916dc8 Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Mon, 25 Mar 2019 18:43:57 +0200 Subject: [PATCH 33/33] Add changeLog entry Add changeLog entry with the additional oid for "Any Policy". --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9deefa5e2..5eebec16d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,8 @@ Features * Add MBEDTLS_REMOVE_3DES_CIPHERSUITES to allow removing 3DES ciphersuites from the default list (enabled by default). See https://sweet32.info/SWEET32_CCS16.pdf. + * Add the Any Policy certificate policy oid, as defined in + rfc 5280 section 4.2.1.4. API Changes * Add a new X.509 API call `mbedtls_x509_parse_der_nocopy()`.