From bd990d6629f48020e30c32926be7acedb6b4683b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 11 Jun 2015 14:49:42 +0200 Subject: [PATCH 01/17] Add ssl_conf_dhm_min_bitlen() --- include/mbedtls/ssl.h | 17 +++++++++++++++++ library/ssl_cli.c | 7 ++++--- library/ssl_tls.c | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index fdd35954e..1d893bbb1 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -577,6 +577,10 @@ struct mbedtls_ssl_config unsigned int badmac_limit; /*!< limit of records with a bad MAC */ #endif +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) + unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */ +#endif + unsigned char max_major_ver; /*!< max. major version used */ unsigned char max_minor_ver; /*!< max. minor version used */ unsigned char min_major_ver; /*!< min. major version used */ @@ -1477,6 +1481,19 @@ int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, cons int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ); #endif /* MBEDTLS_DHM_C && defined(MBEDTLS_SSL_SRV_C) */ +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) +/** + * \brief Set the minimum length for Diffie-Hellman parameters. + * (Client-side only.) + * (Default: 1024 bits.) + * + * \param conf SSL configuration + * \param bitlen Minimum bit length of the DHM prime + */ +void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, + unsigned int bitlen ); +#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ + #if defined(MBEDTLS_SSL_SET_CURVES) /** * \brief Set the allowed curves in order of preference. diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 6eb190c57..72ce76f7f 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1648,10 +1648,11 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char * return( ret ); } - if( ssl->handshake->dhm_ctx.len < 64 || - ssl->handshake->dhm_ctx.len > 512 ) + if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (DHM length)" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d", + ssl->handshake->dhm_ctx.len * 8, + ssl->conf->dhm_min_bitlen ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ee32502ce..a0cd3d28b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5458,6 +5458,17 @@ int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context } #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */ +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) +/* + * Set the minimum length for Diffie-Hellman parameters + */ +void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, + unsigned int bitlen ) +{ + conf->dhm_min_bitlen = bitlen; +} +#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ + #if defined(MBEDTLS_SSL_SET_CURVES) /* * Set the allowed elliptic curves @@ -6665,6 +6676,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->renego_period[7] = 0x00; #endif +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) + conf->dhm_min_bitlen = 1024; +#endif + #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) if( endpoint == MBEDTLS_SSL_IS_SERVER ) { From 90966823524f2b229648b4464d65bca629664a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 11 Jun 2015 17:02:29 +0200 Subject: [PATCH 02/17] Add dhmlen option in ssl_client2.c --- programs/ssl/ssl_client2.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 960412a95..eabcbdc64 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -95,6 +95,7 @@ int main( void ) #define DFL_MFL_CODE MBEDTLS_SSL_MAX_FRAG_LEN_NONE #define DFL_TRUNC_HMAC -1 #define DFL_RECSPLIT -1 +#define DFL_DHMLEN -1 #define DFL_RECONNECT 0 #define DFL_RECO_DELAY 0 #define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED @@ -164,6 +165,13 @@ int main( void ) #define USAGE_RECSPLIT #endif +#if defined(MBEDTLS_DHM_C) +#define USAGE_DHMLEN \ + " dhmlen=%%d default: (library default: 1024 bits)\n" +#else +#define USAGE_DHMLEN +#endif + #if defined(MBEDTLS_SSL_ALPN) #define USAGE_ALPN \ " alpn=%%s default: \"\" (disabled)\n" \ @@ -246,6 +254,7 @@ int main( void ) USAGE_EMS \ USAGE_ETM \ USAGE_RECSPLIT \ + USAGE_DHMLEN \ "\n" \ " arc4=%%d default: (library default: 0)\n" \ " min_version=%%s default: (library default: tls1)\n" \ @@ -289,6 +298,7 @@ struct options unsigned char mfl_code; /* code for maximum fragment length */ int trunc_hmac; /* negotiate truncated hmac or not */ int recsplit; /* enable record splitting? */ + int dhmlen; /* minimum DHM params len in bits */ int reconnect; /* attempt to resume session */ int reco_delay; /* delay in seconds before resuming session */ int tickets; /* enable / disable session tickets */ @@ -468,6 +478,7 @@ int main( int argc, char *argv[] ) opt.mfl_code = DFL_MFL_CODE; opt.trunc_hmac = DFL_TRUNC_HMAC; opt.recsplit = DFL_RECSPLIT; + opt.dhmlen = DFL_DHMLEN; opt.reconnect = DFL_RECONNECT; opt.reco_delay = DFL_RECO_DELAY; opt.tickets = DFL_TICKETS; @@ -758,6 +769,12 @@ int main( int argc, char *argv[] ) if( opt.recsplit < 0 || opt.recsplit > 1 ) goto usage; } + else if( strcmp( p, "dhmlen" ) == 0 ) + { + opt.dhmlen = atoi( q ); + if( opt.dhmlen < 0 ) + goto usage; + } else goto usage; } @@ -1091,6 +1108,11 @@ int main( int argc, char *argv[] ) : MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ); #endif +#if defined(MBEDTLS_DHM_C) + if( opt.dhmlen != DFL_DHMLEN ) + mbedtls_ssl_conf_dhm_min_bitlen( &conf, opt.dhmlen ); +#endif + #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 ) From 7a010aabdeedcc6a676cfe47d8a44c810b5f11d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 12 Jun 2015 11:19:10 +0200 Subject: [PATCH 03/17] Add tests for dhm_min_bitlen --- tests/data_files/dh.1000.pem | 34 +++++++++++++++++++++++++++++++++ tests/ssl-opt.sh | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 tests/data_files/dh.1000.pem diff --git a/tests/data_files/dh.1000.pem b/tests/data_files/dh.1000.pem new file mode 100644 index 000000000..172f19fb4 --- /dev/null +++ b/tests/data_files/dh.1000.pem @@ -0,0 +1,34 @@ + +Recommended key length: 160 bits + +generator: + 23:84:3c:0d:55:8c:b9:7d:a9:d5:9a:80:82:fb:50: + 89:29:71:8e:8e:a1:29:2e:df:db:01:34:41:e7:66: + fa:60:dc:bc:34:83:45:70:e0:61:e9:a6:25:23:c2: + 77:33:a9:8a:90:94:21:ff:84:d2:7b:36:39:9b:e5: + f0:88:2b:35:98:64:28:58:27:be:fa:bf:e3:60:cc: + c4:61:60:59:78:a7:e1:a3:b3:a7:3e:7e:5b:a8:d7: + b7:ba:25:0e:b1:9e:79:03:b5:83:ba:43:34:b6:c1: + ce:45:66:72:07:64:8a:af:14:d8:ae:18:19:ba:25: + a6:d9:36:f8:8c: + +prime: + 9e:a4:a8:c4:29:fe:76:18:02:4f:76:c9:29:0e:f2: + ba:0d:92:08:9d:d9:b3:28:41:5d:88:4e:fe:3c:ae: + c1:d4:3e:7e:fb:d8:2c:bf:7b:63:70:99:9e:c4:ac: + d0:1e:7c:4e:22:07:d2:b5:f9:9a:9e:52:e2:97:9d: + c3:cb:0d:66:33:75:95:a7:96:6e:69:ec:16:bd:06: + 4a:1a:dc:b2:d4:29:23:ab:2e:8f:7f:6a:84:1d:82: + 23:6e:42:8c:1e:70:3d:21:bb:b9:b9:8f:f9:fd:9c: + 53:08:e4:e8:5a:04:ca:5f:8f:73:55:ac:e1:41:20: + c7:43:fa:8f:99: + + +-----BEGIN DH PARAMETERS----- +MIIBAwJ+AJ6kqMQp/nYYAk92ySkO8roNkgid2bMoQV2ITv48rsHUPn772Cy/e2Nw +mZ7ErNAefE4iB9K1+ZqeUuKXncPLDWYzdZWnlm5p7Ba9Bkoa3LLUKSOrLo9/aoQd +giNuQowecD0hu7m5j/n9nFMI5OhaBMpfj3NVrOFBIMdD+o+ZAn0jhDwNVYy5fanV +moCC+1CJKXGOjqEpLt/bATRB52b6YNy8NINFcOBh6aYlI8J3M6mKkJQh/4TSezY5 +m+XwiCs1mGQoWCe++r/jYMzEYWBZeKfho7OnPn5bqNe3uiUOsZ55A7WDukM0tsHO +RWZyB2SKrxTYrhgZuiWm2Tb4jAICAKA= +-----END DH PARAMETERS----- diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index fab278f90..934f77214 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -2304,6 +2304,43 @@ run_test "DHM parameters: other parameters" \ -c "value of 'DHM: P ' (1024 bits)" \ -c "value of 'DHM: G ' (2 bits)" +# Tests for DHM client-side size checking + +run_test "DHM size: server default, client default, OK" \ + "$P_SRV" \ + "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \ + debug_level=1" \ + 0 \ + -C "DHM prime too short:" + +run_test "DHM size: server default, client 2048, OK" \ + "$P_SRV" \ + "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \ + debug_level=1 dhmlen=2048" \ + 0 \ + -C "DHM prime too short:" + +run_test "DHM size: server 1024, client default, OK" \ + "$P_SRV dhm_file=data_files/dhparams.pem" \ + "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \ + debug_level=1" \ + 0 \ + -C "DHM prime too short:" + +run_test "DHM size: server 1000, client default, rejected" \ + "$P_SRV dhm_file=data_files/dh.1000.pem" \ + "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \ + debug_level=1" \ + 1 \ + -c "DHM prime too short:" + +run_test "DHM size: server default, client 2049, rejected" \ + "$P_SRV" \ + "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \ + debug_level=1 dhmlen=2049" \ + 1 \ + -c "DHM prime too short:" + # Tests for PSK callback run_test "PSK callback: psk, no callback" \ From bc7bbbc85a3ae244ae2994591150df73777fb00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 15 Jun 2015 11:58:45 +0200 Subject: [PATCH 04/17] Remove duplicated tests for x509_verify_info() --- tests/suites/test_suite_x509parse.data | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 5f3fff867..e3bc13001 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -283,27 +283,6 @@ x509_verify_info:MBEDTLS_X509_BADCERT_MISSING:" ! ":" ! Certificate was missin X509 Verify Information: two issues, with prefix x509_verify_info:MBEDTLS_X509_BADCERT_EXPIRED | MBEDTLS_X509_BADCRL_EXPIRED:" ! ":" ! The certificate validity has expired\n ! The CRL is expired\n" -X509 Verify Information: empty -x509_verify_info:0:"":"" - -X509 Verify Information: one issue -x509_verify_info:MBEDTLS_X509_BADCERT_MISSING:"":"Certificate was missing\n" - -X509 Verify Information: two issues -x509_verify_info:MBEDTLS_X509_BADCERT_EXPIRED | MBEDTLS_X509_BADCRL_EXPIRED:"":"The certificate validity has expired\nThe CRL is expired\n" - -X509 Verify Information: two issues, one unknown -x509_verify_info:MBEDTLS_X509_BADCERT_OTHER | 0x8000:"":"Other reason (can be used by verify callback)\nUnknown reason (this should not happen)\n" - -X509 Verify Information: empty, with prefix -x509_verify_info:0:" ! ":"" - -X509 Verify Information: one issue, with prefix -x509_verify_info:MBEDTLS_X509_BADCERT_MISSING:" ! ":" ! Certificate was missing\n" - -X509 Verify Information: two issues, with prefix -x509_verify_info:MBEDTLS_X509_BADCERT_EXPIRED | MBEDTLS_X509_BADCRL_EXPIRED:" ! ":" ! The certificate validity has expired\n ! The CRL is expired\n" - X509 Get Distinguished Name #1 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C mbedtls_x509_dn_gets:"data_files/server1.crt":"subject":"C=NL, O=PolarSSL, CN=PolarSSL Server 1" From 9505164ef4d70806b836cbb889c9cc190fd35ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 15 Jun 2015 10:39:46 +0200 Subject: [PATCH 05/17] Create cert profile API (unimplemented yet) --- include/mbedtls/x509.h | 7 ++++ include/mbedtls/x509_crt.h | 48 ++++++++++++++++++++++ library/x509_crt.c | 55 +++++++++++++++++++++----- tests/suites/test_suite_x509parse.data | 2 +- 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h index 7cb0d468c..597053c7d 100644 --- a/include/mbedtls/x509.h +++ b/include/mbedtls/x509.h @@ -97,6 +97,13 @@ #define MBEDTLS_X509_BADCERT_KEY_USAGE 0x0800 /**< Usage does not match the keyUsage extension. */ #define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE 0x1000 /**< Usage does not match the extendedKeyUsage extension. */ #define MBEDTLS_X509_BADCERT_NS_CERT_TYPE 0x2000 /**< Usage does not match the nsCertType extension. */ +#define MBEDTLS_X509_BADCERT_BAD_MD 0x4000 /**< The certificate is signed with an unacceptable hash. */ +#define MBEDTLS_X509_BADCERT_BAD_PK 0x8000 /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ +#define MBEDTLS_X509_BADCERT_BAD_KEY 0x010000 /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */ +#define MBEDTLS_X509_BADCRL_BAD_MD 0x020000 /**< The CRL is signed with an unacceptable hash. */ +#define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ +#define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */ + /* \} name */ /* \} addtogroup x509_module */ diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index 8aabfdeff..7acee5779 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -94,6 +94,20 @@ typedef struct mbedtls_x509_crt } mbedtls_x509_crt; +/* + * Security profile for certificate verification + * + * All lists are terminated by the respective _NONE value. + */ +typedef struct +{ + const mbedtls_md_type_t *allowed_mds; /**< MDs for signatures */ + const mbedtls_pk_type_t *allowed_pks; /**< PK algs for signatures */ + size_t rsa_min_bitlen; /**< Minimum size for RSA keys */ + const mbedtls_ecp_group *allowed_curves;/**< Elliptic curves for ECDSA */ +} +mbedtls_x509_crt_profile; + #define MBEDTLS_X509_CRT_VERSION_1 0 #define MBEDTLS_X509_CRT_VERSION_2 1 #define MBEDTLS_X509_CRT_VERSION_3 2 @@ -232,6 +246,9 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, * \note In case verification failed, the results can be displayed * using \c mbedtls_x509_crt_verify_info() * + * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the + * default security profile. + * * \param crt a certificate to be verified * \param trust_ca the trusted CA chain * \param ca_crl the CRL chain for trusted CA's @@ -255,6 +272,37 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy ); +/** + * \brief Verify the certificate signature according to profile + * + * \note Same as \c mbedtls_x509_crt_verify(), but with explicit + * security profile. + * + * \param crt a certificate to be verified + * \param trust_ca the trusted CA chain + * \param ca_crl the CRL chain for trusted CA's + * \param profile security profile for verification + * \param cn expected Common Name (can be set to + * NULL if the CN must not be verified) + * \param flags result of the verification + * \param f_vrfy verification function + * \param p_vrfy verification parameter + * + * \return 0 if successful or MBEDTLS_ERR_X509_CERT_VERIFY_FAILED + * in which case *flags will have one or more + * MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX flags + * set, + * or another error in case of a fatal error encountered + * during the verification process. + */ +int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, + mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); + #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) /** * \brief Check usage of certificate against keyUsage extension. diff --git a/library/x509_crt.c b/library/x509_crt.c index a26715a6b..e3d7cc739 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1401,6 +1401,12 @@ static const struct x509_crt_verify_string x509_crt_verify_strings[] = { { MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" }, { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" }, { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" }, + { MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." }, + { MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, + { MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." }, + { MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." }, + { MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, + { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." }, { 0, NULL } }; @@ -1502,7 +1508,8 @@ int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509 * Check that the given certificate is valid according to the CRL. */ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, - mbedtls_x509_crl *crl_list) + mbedtls_x509_crl *crl_list, + const mbedtls_x509_crt_profile *profile ) { int flags = 0; unsigned char hash[MBEDTLS_MD_MAX_SIZE]; @@ -1554,6 +1561,8 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); + (void) profile; /* WIP:TODO: check profile */ + if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), crl_list->sig.p, crl_list->sig.len ) != 0 ) @@ -1764,7 +1773,9 @@ static int x509_crt_check_parent( const mbedtls_x509_crt *child, static int x509_crt_verify_top( mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, int path_cnt, uint32_t *flags, + mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + int path_cnt, uint32_t *flags, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy ) { @@ -1796,6 +1807,8 @@ static int x509_crt_verify_top( else mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ); + (void) profile; /* WIP:TODO: check profile */ + for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) { if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 ) @@ -1846,7 +1859,7 @@ static int x509_crt_verify_top( { #if defined(MBEDTLS_X509_CRL_PARSE_C) /* Check trusted CA's CRL for the chain's top crt */ - *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl ); + *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile ); #else ((void) ca_crl); #endif @@ -1880,8 +1893,10 @@ static int x509_crt_verify_top( } static int x509_crt_verify_child( - mbedtls_x509_crt *child, mbedtls_x509_crt *parent, mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, int path_cnt, uint32_t *flags, + mbedtls_x509_crt *child, mbedtls_x509_crt *parent, + mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + int path_cnt, uint32_t *flags, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy ) { @@ -1891,6 +1906,8 @@ static int x509_crt_verify_child( mbedtls_x509_crt *grandparent; const mbedtls_md_info_t *md_info; + (void) profile; /* WIP */ + /* path_cnt is 0 for the first intermediate CA */ if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) { @@ -1914,6 +1931,8 @@ static int x509_crt_verify_child( } else { + (void) profile; /* WIP:TODO: check profile */ + mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ); if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, @@ -1926,7 +1945,7 @@ static int x509_crt_verify_child( #if defined(MBEDTLS_X509_CRL_PARSE_C) /* Check trusted CA's CRL for the given crt */ - *flags |= x509_crt_verifycrl(child, parent, ca_crl); + *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile ); #endif /* Look for a grandparent upwards the chain */ @@ -1942,14 +1961,14 @@ static int x509_crt_verify_child( /* Is our parent part of the chain or at the top? */ if( grandparent != NULL ) { - ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, + ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, profile, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); } else { - ret = x509_crt_verify_top( parent, trust_ca, ca_crl, + ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); @@ -1974,6 +1993,22 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, const char *cn, uint32_t *flags, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy ) +{ + return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl, + NULL /* WIP */, cn, flags, f_vrfy, p_vrfy ) ); +} + + +/* + * Verify the certificate validity, with profile + */ +int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, + mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) { size_t cn_len; int ret; @@ -2044,14 +2079,14 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, /* Are we part of the chain or at the top? */ if( parent != NULL ) { - ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, + ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile, pathlen, flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); } else { - ret = x509_crt_verify_top( crt, trust_ca, ca_crl, + ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile, pathlen, flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index e3bc13001..932712a6f 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -272,7 +272,7 @@ X509 Verify Information: two issues x509_verify_info:MBEDTLS_X509_BADCERT_EXPIRED | MBEDTLS_X509_BADCRL_EXPIRED:"":"The certificate validity has expired\nThe CRL is expired\n" X509 Verify Information: two issues, one unknown -x509_verify_info:MBEDTLS_X509_BADCERT_OTHER | 0x8000:"":"Other reason (can be used by verify callback)\nUnknown reason (this should not happen)\n" +x509_verify_info:MBEDTLS_X509_BADCERT_OTHER | 0x80000000:"":"Other reason (can be used by verify callback)\nUnknown reason (this should not happen)\n" X509 Verify Information: empty, with prefix x509_verify_info:0:" ! ":"" From 88db5da1177c2e07c0da85d43e2ecabd5a898d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 15 Jun 2015 14:34:59 +0200 Subject: [PATCH 06/17] Add pre-defined profiles for cert verification --- include/mbedtls/x509_crt.h | 26 ++++++-- library/ecp.c | 2 + library/md.c | 3 + library/x509_crt.c | 118 ++++++++++++++++++++++++++++++++++++- 4 files changed, 144 insertions(+), 5 deletions(-) diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index 7acee5779..9a23c06e2 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -94,8 +94,8 @@ typedef struct mbedtls_x509_crt } mbedtls_x509_crt; -/* - * Security profile for certificate verification +/** + * Security profile for certificate verification. * * All lists are terminated by the respective _NONE value. */ @@ -103,8 +103,9 @@ typedef struct { const mbedtls_md_type_t *allowed_mds; /**< MDs for signatures */ const mbedtls_pk_type_t *allowed_pks; /**< PK algs for signatures */ - size_t rsa_min_bitlen; /**< Minimum size for RSA keys */ - const mbedtls_ecp_group *allowed_curves;/**< Elliptic curves for ECDSA */ + const mbedtls_ecp_group_id *allowed_curves; /**< Elliptic curves */ + size_t rsa_min_bitlen; /**< Minimum size for RSA keys + (must be non-zero) */ } mbedtls_x509_crt_profile; @@ -134,6 +135,23 @@ typedef struct mbedtls_x509write_cert mbedtls_x509write_cert; #if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * Default security profile. Should provide a good balance between security + * and compatibility with current deployments. + */ +extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default; + +/** + * Expected next default profile. Recommended for new deployments. + * Currently targets a 128-bit security level, except for RSA-2048. + */ +extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next; + +/** + * NSA Suite B profile. + */ +extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb; + /** * \brief Parse a single DER formatted certificate and add it * to the chained list. diff --git a/library/ecp.c b/library/ecp.c index 31197ce49..b733bcc10 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -124,6 +124,8 @@ typedef enum * * Curves are listed in order: largest curves first, and for a given size, * fastest curves first. This provides the default order for the SSL module. + * + * Reminder: update profiles in x509_crt.c when adding a new curves! */ static const mbedtls_ecp_curve_info ecp_supported_curves[] = { diff --git a/library/md.c b/library/md.c index 381ffc404..1d6191fc2 100644 --- a/library/md.c +++ b/library/md.c @@ -54,6 +54,9 @@ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = v; while( n-- ) *p++ = 0; } +/* + * Reminder: update profiles in x509_crt.c when adding a new hash! + */ static const int supported_digests[] = { #if defined(MBEDTLS_SHA512_C) diff --git a/library/x509_crt.c b/library/x509_crt.c index e3d7cc739..8ed3468c7 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -81,6 +81,122 @@ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = v; while( n-- ) *p++ = 0; } +/* + * Default profile + */ +static const mbedtls_md_type_t x509_prof_default_mds[] = +{ + MBEDTLS_MD_SHA1, + MBEDTLS_MD_RIPEMD160, + MBEDTLS_MD_SHA224, + MBEDTLS_MD_SHA256, + MBEDTLS_MD_SHA384, + MBEDTLS_MD_SHA512, + MBEDTLS_MD_NONE +}; + +static const mbedtls_pk_type_t x509_prof_default_pks[] = +{ + MBEDTLS_PK_RSA, + MBEDTLS_PK_ECDSA, + MBEDTLS_PK_NONE +}; + +#if defined(MBEDTLS_ECP_C) +static const mbedtls_ecp_group_id x509_prof_default_curves[] = +{ + MBEDTLS_ECP_DP_SECP192R1, + MBEDTLS_ECP_DP_SECP224R1, + MBEDTLS_ECP_DP_SECP256R1, + MBEDTLS_ECP_DP_SECP384R1, + MBEDTLS_ECP_DP_SECP521R1, + MBEDTLS_ECP_DP_BP256R1, + MBEDTLS_ECP_DP_BP384R1, + MBEDTLS_ECP_DP_BP512R1, + MBEDTLS_ECP_DP_SECP192K1, + MBEDTLS_ECP_DP_SECP224K1, + MBEDTLS_ECP_DP_SECP256K1, +}; +#else +static const mbedtls_ecp_group_id *x509_prof_default_curves = NULL; +#endif + +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = +{ + x509_prof_default_mds, + x509_prof_default_pks, + x509_prof_default_curves, + 2048, +}; + +/* + * Next-default profile + */ +static const mbedtls_md_type_t x509_prof_next_mds[] = +{ + MBEDTLS_MD_SHA256, + MBEDTLS_MD_SHA384, + MBEDTLS_MD_SHA512, + MBEDTLS_MD_NONE +}; + +#if defined(MBEDTLS_ECP_C) +static const mbedtls_ecp_group_id x509_prof_next_curves[] = +{ + MBEDTLS_ECP_DP_SECP256R1, + MBEDTLS_ECP_DP_SECP384R1, + MBEDTLS_ECP_DP_SECP521R1, + MBEDTLS_ECP_DP_BP256R1, + MBEDTLS_ECP_DP_BP384R1, + MBEDTLS_ECP_DP_BP512R1, + MBEDTLS_ECP_DP_SECP256K1, +}; +#else +static const mbedtls_ecp_group_id *x509_prof_next_curves = NULL; +#endif + +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = +{ + x509_prof_next_mds, + x509_prof_default_pks, + x509_prof_next_curves, + 2048, +}; + +/* + * NSA Suite B Profile + */ +static const mbedtls_md_type_t x509_prof_suiteb_mds[] = +{ + MBEDTLS_MD_SHA256, + MBEDTLS_MD_SHA384, + MBEDTLS_MD_NONE +}; + +static const mbedtls_pk_type_t x509_prof_suiteb_pks[] = +{ + MBEDTLS_PK_ECDSA, + MBEDTLS_PK_NONE +}; + +#if defined(MBEDTLS_ECP_C) +static const mbedtls_ecp_group_id x509_prof_suiteb_curves[] = +{ + MBEDTLS_ECP_DP_SECP256R1, + MBEDTLS_ECP_DP_SECP384R1, +}; +#else +static const mbedtls_ecp_group_id *x509_prof_suiteb_curves = NULL; +#endif + +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = +{ + x509_prof_suiteb_mds, + x509_prof_suiteb_pks, + x509_prof_suiteb_curves, + 2048, +}; + /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ @@ -1995,7 +2111,7 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, void *p_vrfy ) { return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl, - NULL /* WIP */, cn, flags, f_vrfy, p_vrfy ) ); + &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) ); } From f8ea856296e556c53741c4635d2399bed6a96c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 15 Jun 2015 15:33:19 +0200 Subject: [PATCH 07/17] Change data structure of profiles to bitfields - allows to express 'none' or 'all' more easily than lists - more compact and easier to declare statically - easier to check too Only drawback: if we ever have more than 32 curves, we'll need an ABI change to make that field a uint64_t. --- include/mbedtls/x509_crt.h | 17 +++-- library/x509_crt.c | 132 +++++++++++-------------------------- 2 files changed, 50 insertions(+), 99 deletions(-) diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index 9a23c06e2..ea0c2cdf5 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -94,18 +94,23 @@ typedef struct mbedtls_x509_crt } mbedtls_x509_crt; +/** + * Build flag from an algorithm/curve identifier (pk, md, ecp) + * Since 0 is always XXX_NONE, ignore it. + */ +#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( id - 1 ) ) + /** * Security profile for certificate verification. * - * All lists are terminated by the respective _NONE value. + * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG(). */ typedef struct { - const mbedtls_md_type_t *allowed_mds; /**< MDs for signatures */ - const mbedtls_pk_type_t *allowed_pks; /**< PK algs for signatures */ - const mbedtls_ecp_group_id *allowed_curves; /**< Elliptic curves */ - size_t rsa_min_bitlen; /**< Minimum size for RSA keys - (must be non-zero) */ + uint32_t allowed_mds; /**< MDs for signatures */ + uint32_t allowed_pks; /**< PK algs for signatures */ + uint32_t allowed_curves; /**< Elliptic curves for ECDSA */ + uint32_t rsa_min_bitlen; /**< Minimum size for RSA keys */ } mbedtls_x509_crt_profile; diff --git a/library/x509_crt.c b/library/x509_crt.c index 8ed3468c7..8d58b9d44 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -84,117 +84,63 @@ static void mbedtls_zeroize( void *v, size_t n ) { /* * Default profile */ -static const mbedtls_md_type_t x509_prof_default_mds[] = -{ - MBEDTLS_MD_SHA1, - MBEDTLS_MD_RIPEMD160, - MBEDTLS_MD_SHA224, - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA384, - MBEDTLS_MD_SHA512, - MBEDTLS_MD_NONE -}; - -static const mbedtls_pk_type_t x509_prof_default_pks[] = -{ - MBEDTLS_PK_RSA, - MBEDTLS_PK_ECDSA, - MBEDTLS_PK_NONE -}; - -#if defined(MBEDTLS_ECP_C) -static const mbedtls_ecp_group_id x509_prof_default_curves[] = -{ - MBEDTLS_ECP_DP_SECP192R1, - MBEDTLS_ECP_DP_SECP224R1, - MBEDTLS_ECP_DP_SECP256R1, - MBEDTLS_ECP_DP_SECP384R1, - MBEDTLS_ECP_DP_SECP521R1, - MBEDTLS_ECP_DP_BP256R1, - MBEDTLS_ECP_DP_BP384R1, - MBEDTLS_ECP_DP_BP512R1, - MBEDTLS_ECP_DP_SECP192K1, - MBEDTLS_ECP_DP_SECP224K1, - MBEDTLS_ECP_DP_SECP256K1, -}; -#else -static const mbedtls_ecp_group_id *x509_prof_default_curves = NULL; -#endif - const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = { - x509_prof_default_mds, - x509_prof_default_pks, - x509_prof_default_curves, + /* Hashes from SHA-1 and above */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ + 0xFFFFFFF, /* Any curve */ 2048, }; /* * Next-default profile */ -static const mbedtls_md_type_t x509_prof_next_mds[] = -{ - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA384, - MBEDTLS_MD_SHA512, - MBEDTLS_MD_NONE -}; - -#if defined(MBEDTLS_ECP_C) -static const mbedtls_ecp_group_id x509_prof_next_curves[] = -{ - MBEDTLS_ECP_DP_SECP256R1, - MBEDTLS_ECP_DP_SECP384R1, - MBEDTLS_ECP_DP_SECP521R1, - MBEDTLS_ECP_DP_BP256R1, - MBEDTLS_ECP_DP_BP384R1, - MBEDTLS_ECP_DP_BP512R1, - MBEDTLS_ECP_DP_SECP256K1, -}; -#else -static const mbedtls_ecp_group_id *x509_prof_next_curves = NULL; -#endif - const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = { - x509_prof_next_mds, - x509_prof_default_pks, - x509_prof_next_curves, + /* Hashes from SHA-256 and above */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ +#if defined(MBEDTLS_ECP_C) + /* Curves at or above 128-bit security level */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ), +#else + 0, +#endif 2048, }; /* * NSA Suite B Profile */ -static const mbedtls_md_type_t x509_prof_suiteb_mds[] = -{ - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA384, - MBEDTLS_MD_NONE -}; - -static const mbedtls_pk_type_t x509_prof_suiteb_pks[] = -{ - MBEDTLS_PK_ECDSA, - MBEDTLS_PK_NONE -}; - -#if defined(MBEDTLS_ECP_C) -static const mbedtls_ecp_group_id x509_prof_suiteb_curves[] = -{ - MBEDTLS_ECP_DP_SECP256R1, - MBEDTLS_ECP_DP_SECP384R1, -}; -#else -static const mbedtls_ecp_group_id *x509_prof_suiteb_curves = NULL; -#endif - const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = { - x509_prof_suiteb_mds, - x509_prof_suiteb_pks, - x509_prof_suiteb_curves, - 2048, + /* Only SHA-256 and 384 */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), + /* Only ECDSA */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ), +#if defined(MBEDTLS_ECP_C) + /* Only NIST P-256 and P-384 */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), +#else + 0, +#endif + 0, }; /* From cbb1f6e5cb7e369468e08cf5f8724a80be1cc437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 15 Jun 2015 16:17:55 +0200 Subject: [PATCH 08/17] Implement cert profile checking --- library/x509_crt.c | 91 ++++++++++++++++++++++++-- tests/suites/test_suite_x509parse.data | 8 +-- 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/library/x509_crt.c b/library/x509_crt.c index 8d58b9d44..8a0bd8b49 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -143,6 +143,65 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = 0, }; +/* + * Check md_alg against profile + * Return 0 if md_alg acceptable for this profile, -1 otherwise + */ +static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, + mbedtls_md_type_t md_alg ) +{ + if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 ) + return( 0 ); + + return( -1 ); +} + +/* + * Check pk_alg against profile + * Return 0 if pk_alg acceptable for this profile, -1 otherwise + */ +static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, + mbedtls_pk_type_t pk_alg ) +{ + if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 ) + return( 0 ); + + return( -1 ); +} + +/* + * Check key against profile + * Return 0 if pk_alg acceptable for this profile, -1 otherwise + */ +static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, + mbedtls_pk_type_t pk_alg, + const mbedtls_pk_context *pk ) +{ +#if defined(MBEDTLS_RSA_C) + if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS ) + { + if( mbedtls_pk_get_size( pk ) >= profile->rsa_min_bitlen ) + return( 0 ); + + return( -1 ); + } +#endif + +#if defined(MBEDTLS_ECDSA_C) + if( pk_alg == MBEDTLS_PK_ECDSA ) + { + mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id; + + if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 ) + return( 0 ); + + return( -1 ); + } +#endif + + return( -1 ); +} + /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ @@ -1611,6 +1670,12 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, /* * Check if CRL is correctly signed by the trusted CA */ + if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 ) + flags |= MBEDTLS_X509_BADCRL_BAD_MD; + + if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 ) + flags |= MBEDTLS_X509_BADCRL_BAD_PK; + md_info = mbedtls_md_info_from_type( crl_list->sig_md ); if( md_info == NULL ) { @@ -1623,7 +1688,8 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); - (void) profile; /* WIP:TODO: check profile */ + if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 ) + flags |= MBEDTLS_X509_BADCERT_BAD_KEY; if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), @@ -1653,6 +1719,7 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, crl_list = crl_list->next; } + return( flags ); } #endif /* MBEDTLS_X509_CRL_PARSE_C */ @@ -1853,6 +1920,12 @@ static int x509_crt_verify_top( if( mbedtls_x509_time_is_future( &child->valid_from ) ) *flags |= MBEDTLS_X509_BADCERT_FUTURE; + if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_MD; + + if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + /* * Child is the top of the chain. Check against the trust_ca list. */ @@ -1869,8 +1942,6 @@ static int x509_crt_verify_top( else mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ); - (void) profile; /* WIP:TODO: check profile */ - for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) { if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 ) @@ -1895,6 +1966,9 @@ static int x509_crt_verify_top( continue; } + if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk, child->sig_md, hash, mbedtls_md_get_size( md_info ), child->sig.p, child->sig.len ) != 0 ) @@ -1983,6 +2057,12 @@ static int x509_crt_verify_child( if( mbedtls_x509_time_is_future( &child->valid_from ) ) *flags |= MBEDTLS_X509_BADCERT_FUTURE; + if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_MD; + + if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + md_info = mbedtls_md_info_from_type( child->sig_md ); if( md_info == NULL ) { @@ -1993,10 +2073,11 @@ static int x509_crt_verify_child( } else { - (void) profile; /* WIP:TODO: check profile */ - mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ); + if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, child->sig_md, hash, mbedtls_md_get_size( md_info ), child->sig.p, child->sig.len ) != 0 ) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 932712a6f..22ff610e8 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -413,11 +413,11 @@ x509_verify:"data_files/server2.crt":"data_files/server1.crt":"data_files/crl_ex X509 Certificate verification #12 (Valid Cert MD4 Digest) depends_on:MBEDTLS_MD4_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 -x509_verify:"data_files/cert_md4.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":0:0:"NULL" +x509_verify:"data_files/cert_md4.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_BAD_MD:"NULL" X509 Certificate verification #13 (Valid Cert MD5 Digest) depends_on:MBEDTLS_MD5_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 -x509_verify:"data_files/cert_md5.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":0:0:"NULL" +x509_verify:"data_files/cert_md5.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_BAD_MD:"NULL" X509 Certificate verification #14 (Valid Cert SHA1 Digest) depends_on:MBEDTLS_SHA1_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 @@ -669,7 +669,7 @@ x509_verify:"data_files/server6-ss-child.crt":"data_files/server5-selfsigned.crt X509 Certificate verification #75 (encoding mismatch) depends_on:MBEDTLS_PEM_PARSE_C -x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl.pem":"NULL":0:0:"NULL" +x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_BAD_KEY:"NULL" X509 Certificate verification #76 (multiple CRLs, not revoked) depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C @@ -693,7 +693,7 @@ x509_verify:"data_files/server1.crt":"data_files/test-ca_cat12.crt":"data_files/ X509 Certificate verification #81 (multiple CRLs, none relevant) depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C -x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl_cat_rsa-ec.pem":"NULL":0:0:"NULL" +x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl_cat_rsa-ec.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_BAD_KEY:"NULL" X509 Parse Selftest depends_on:MBEDTLS_SHA1_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CERTS_C From 6e3ee3ad43e2a194bdf462fb9ef9a46edad6484c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 10:58:20 +0200 Subject: [PATCH 09/17] Add mbedtls_ssl_conf_cert_profile() --- include/mbedtls/ssl.h | 10 ++++++++++ library/ssl_tls.c | 21 +++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 1d893bbb1..4bca71c8c 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -529,6 +529,7 @@ struct mbedtls_ssl_config #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ #if defined(MBEDTLS_X509_CRT_PARSE_C) + const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ mbedtls_x509_crt *ca_chain; /*!< trusted CAs */ mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ @@ -1351,6 +1352,15 @@ void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, int major, int minor ); #if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Set the X.509 security profile used for verification + * + * \param conf SSL configuration + * \param profile Profile to use + */ +void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, + mbedtls_x509_crt_profile *profile ); + /** * \brief Set the data required to verify peer certificate * diff --git a/library/ssl_tls.c b/library/ssl_tls.c index a0cd3d28b..9ce9739e7 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4064,10 +4064,13 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) /* * Main check: verify certificate */ - ret = mbedtls_x509_crt_verify( ssl->session_negotiate->peer_cert, - ca_chain, ca_crl, ssl->hostname, - &ssl->session_negotiate->verify_result, - ssl->conf->f_vrfy, ssl->conf->p_vrfy ); + ret = mbedtls_x509_crt_verify_with_profile( + ssl->session_negotiate->peer_cert, + ca_chain, ca_crl, + ssl->conf->cert_profile, + ssl->hostname, + &ssl->session_negotiate->verify_result, + ssl->conf->f_vrfy, ssl->conf->p_vrfy ); if( ret != 0 ) { @@ -5292,6 +5295,12 @@ void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, } #if defined(MBEDTLS_X509_CRT_PARSE_C) +void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, + mbedtls_x509_crt_profile *profile ) +{ + conf->cert_profile = profile; +} + /* Append a new keycert entry to a (possibly empty) list */ static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, mbedtls_x509_crt *cert, @@ -6636,6 +6645,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = mbedtls_ssl_list_ciphersuites(); +#if defined(MBEDTLS_X509_CRT_PARSE_C) + conf->cert_profile = &mbedtls_x509_crt_profile_default; +#endif + #if defined(MBEDTLS_ARC4_C) conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED; #endif From b541da6ef394d1da303a7408821c100a56a27bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 11:43:30 +0200 Subject: [PATCH 10/17] Fix define for ssl_conf_curves() This is a security feature, it shouldn't be optional. --- include/mbedtls/compat-1.3.h | 3 --- include/mbedtls/config.h | 14 -------------- include/mbedtls/ssl.h | 6 +++--- include/mbedtls/ssl_internal.h | 2 +- library/ssl_cli.c | 6 +++--- library/ssl_srv.c | 2 +- library/ssl_tls.c | 12 ++++++------ library/version_features.c | 3 --- scripts/data_files/rename-1.3-2.0.txt | 1 - 9 files changed, 14 insertions(+), 35 deletions(-) diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h index 8a3ab96dc..0af0a9eb5 100644 --- a/include/mbedtls/compat-1.3.h +++ b/include/mbedtls/compat-1.3.h @@ -585,9 +585,6 @@ #if defined MBEDTLS_SSL_SESSION_TICKETS #define POLARSSL_SSL_SESSION_TICKETS MBEDTLS_SSL_SESSION_TICKETS #endif -#if defined MBEDTLS_SSL_SET_CURVES -#define POLARSSL_SSL_SET_CURVES MBEDTLS_SSL_SET_CURVES -#endif #if defined MBEDTLS_SSL_SRV_C #define POLARSSL_SSL_SRV_C MBEDTLS_SSL_SRV_C #endif diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index f0d293c08..02dd96934 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1154,20 +1154,6 @@ */ #define MBEDTLS_SSL_TRUNCATED_HMAC -/** - * \def MBEDTLS_SSL_SET_CURVES - * - * Enable mbedtls_ssl_conf_curves(). - * - * This is disabled by default since it breaks binary compatibility with the - * 1.3.x line. If you choose to enable it, you will need to rebuild your - * application against the new header files, relinking will not be enough. - * It will be enabled by default, or no longer an option, in the 1.4 branch. - * - * Uncomment to make mbedtls_ssl_conf_curves() available. - */ -//#define MBEDTLS_SSL_SET_CURVES - /** * \def MBEDTLS_THREADING_ALT * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 4bca71c8c..318ca4622 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -535,7 +535,7 @@ struct mbedtls_ssl_config mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */ #endif @@ -1504,7 +1504,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, unsigned int bitlen ); #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) /** * \brief Set the allowed curves in order of preference. * (Default: all defined curves.) @@ -1524,7 +1524,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, * terminated by MBEDTLS_ECP_DP_NONE. */ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, const mbedtls_ecp_group_id *curves ); -#endif /* MBEDTLS_SSL_SET_CURVES */ +#endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_X509_CRT_PARSE_C) /** diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 122c1ee83..e074ce29e 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -375,7 +375,7 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) int mbedtls_ssl_curve_is_acceptable( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); #endif diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 72ce76f7f..3d3f3d17f 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -255,7 +255,7 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, unsigned char *elliptic_curve_list = p + 6; size_t elliptic_curve_len = 0; const mbedtls_ecp_curve_info *info; -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) const mbedtls_ecp_group_id *grp_id; #else ((void) ssl); @@ -265,7 +265,7 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) { info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); @@ -1683,7 +1683,7 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) if( ! mbedtls_ssl_curve_is_acceptable( ssl, ssl->handshake->ecdh_ctx.grp.id ) ) #else if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 7db5a3ca6..554a55239 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -2641,7 +2641,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) * } ServerECDHParams; */ const mbedtls_ecp_curve_info **curve = NULL; -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) const mbedtls_ecp_group_id *gid; /* Match our preference list against the offered curves */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 9ce9739e7..7a1284aab 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4081,7 +4081,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) * Secondary checks: always done, but change 'ret' only if it was 0 */ -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) { const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk; @@ -4094,7 +4094,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; } } -#endif /* MBEDTLS_SSL_SET_CURVES */ +#endif /* MBEDTLS_ECP_C */ if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert, ciphersuite_info, @@ -5478,7 +5478,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, } #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) /* * Set the allowed elliptic curves */ @@ -6665,7 +6665,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED; #endif -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) conf->curve_list = mbedtls_ecp_grp_id_list( ); #endif @@ -6804,7 +6804,7 @@ mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ) } } -#if defined(MBEDTLS_SSL_SET_CURVES) +#if defined(MBEDTLS_ECP_C) /* * Check is a curve proposed by the peer is in our list. * Return 1 if we're willing to use it, 0 otherwise. @@ -6819,7 +6819,7 @@ int mbedtls_ssl_curve_is_acceptable( const mbedtls_ssl_context *ssl, mbedtls_ecp return( 0 ); } -#endif /* MBEDTLS_SSL_SET_CURVES */ +#endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_X509_CRT_PARSE_C) int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, diff --git a/library/version_features.c b/library/version_features.c index e534b3219..7ad0f02b3 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -385,9 +385,6 @@ static const char *features[] = { #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) "MBEDTLS_SSL_TRUNCATED_HMAC", #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ -#if defined(MBEDTLS_SSL_SET_CURVES) - "MBEDTLS_SSL_SET_CURVES", -#endif /* MBEDTLS_SSL_SET_CURVES */ #if defined(MBEDTLS_THREADING_ALT) "MBEDTLS_THREADING_ALT", #endif /* MBEDTLS_THREADING_ALT */ diff --git a/scripts/data_files/rename-1.3-2.0.txt b/scripts/data_files/rename-1.3-2.0.txt index d39509154..bfe2eb2d7 100644 --- a/scripts/data_files/rename-1.3-2.0.txt +++ b/scripts/data_files/rename-1.3-2.0.txt @@ -881,7 +881,6 @@ POLARSSL_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_2 POLARSSL_SSL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION POLARSSL_SSL_SERVER_NAME_INDICATION MBEDTLS_SSL_SERVER_NAME_INDICATION POLARSSL_SSL_SESSION_TICKETS MBEDTLS_SSL_SESSION_TICKETS -POLARSSL_SSL_SET_CURVES MBEDTLS_SSL_SET_CURVES POLARSSL_SSL_SRV_C MBEDTLS_SSL_SRV_C POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO From 27716cc1da66fbf98f212428998e7d8488eccb4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 11:49:39 +0200 Subject: [PATCH 11/17] Clarify a point in the documentation --- include/mbedtls/ssl.h | 10 +++++++++- include/mbedtls/x509_crt.h | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 318ca4622..c1fca1904 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1517,7 +1517,15 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, * use. The server can override our preference order. * * Both sides: limits the set of curves used by peer to the - * listed curves for any use (ECDH(E), certificates). + * listed curves for any use ECDHE and the end-entity + * certificate. + * + * \note This has no influence on which curve are allowed inside the + * certificate chains, see \c mbedtls_ssl_conf_cert_profile() + * for that. For example, if the peer's certificate chain is + * EE -> CA_int -> CA_root, then the allowed curves for EE are + * controlled by \c mbedtls_ssl_conf_curves() but for CA_int + * and CA_root it's \c mbedtls_ssl_conf_cert_profile(). * * \param conf SSL configuration * \param curves Ordered list of allowed curves, diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index ea0c2cdf5..9f4160f90 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -301,6 +301,10 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, * \note Same as \c mbedtls_x509_crt_verify(), but with explicit * security profile. * + * \note The restrictions on keys (RSA minimum size, allowed curves + * for ECDSA) only applys to (intermediate) CAs, not to the + * end-entity certificate. + * * \param crt a certificate to be verified * \param trust_ca the trusted CA chain * \param ca_crl the CRL chain for trusted CA's From a83e4e2bf5fbb8607b292b6a880c050e3429decf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 11:53:48 +0200 Subject: [PATCH 12/17] Extra check in verify_with_profile() This could happen if someone doesn't set the SSL configuration properly. In that case we don't want to segfault... --- library/x509_crt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/x509_crt.c b/library/x509_crt.c index 8a0bd8b49..bedc6e98f 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -2160,6 +2160,9 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, mbedtls_x509_name *name; mbedtls_x509_sequence *cur = NULL; + if( profile == NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + *flags = 0; if( cn != NULL ) From 9d412d872ceb04ac143258ae8aca5b66337147f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 12:10:46 +0200 Subject: [PATCH 13/17] Small internal changes in curve checking - switch from is_acceptable to the more usual check - add NULL check just in case user screwed up config --- include/mbedtls/ssl_internal.h | 2 +- library/ssl_cli.c | 2 +- library/ssl_tls.c | 13 ++++++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index e074ce29e..22b07bc17 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -376,7 +376,7 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); #if defined(MBEDTLS_ECP_C) -int mbedtls_ssl_curve_is_acceptable( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); +int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); #endif #if defined(MBEDTLS_X509_CRT_PARSE_C) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 3d3f3d17f..e4f06864e 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1684,7 +1684,7 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); #if defined(MBEDTLS_ECP_C) - if( ! mbedtls_ssl_curve_is_acceptable( ssl, ssl->handshake->ecdh_ctx.grp.id ) ) + if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 ) #else if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || ssl->handshake->ecdh_ctx.grp.nbits > 521 ) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 7a1284aab..9f241576d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4087,7 +4087,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) /* If certificate uses an EC key, make sure the curve is OK */ if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) && - ! mbedtls_ssl_curve_is_acceptable( ssl, mbedtls_pk_ec( *pk )->grp.id ) ) + mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); if( ret == 0 ) @@ -6807,17 +6807,20 @@ mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ) #if defined(MBEDTLS_ECP_C) /* * Check is a curve proposed by the peer is in our list. - * Return 1 if we're willing to use it, 0 otherwise. + * Return 0 if we're willing to use it, -1 otherwise. */ -int mbedtls_ssl_curve_is_acceptable( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) +int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) { const mbedtls_ecp_group_id *gid; + if( ssl->conf->curve_list == NULL ) + return( -1 ); + for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) if( *gid == grp_id ) - return( 1 ); + return( 0 ); - return( 0 ); + return( -1 ); } #endif /* MBEDTLS_ECP_C */ From 36a8b575a9d5fd6e3d53f9737403b05accc2cc7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 12:43:26 +0200 Subject: [PATCH 14/17] Create API for mbedtls_ssl_conf_sig_hashes(). Not implemented yet. --- include/mbedtls/ssl.h | 41 +++++++++++++++++++++++++++++++++++++++-- library/ssl_cli.c | 9 ++------- library/ssl_tls.c | 17 ++++++++++++++++- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index c1fca1904..49ef310e1 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -70,6 +70,12 @@ #define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED #endif +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED +#endif + /* * SSL Error codes */ @@ -529,12 +535,16 @@ struct mbedtls_ssl_config #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ #if defined(MBEDTLS_X509_CRT_PARSE_C) - const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ + const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ mbedtls_x509_crt *ca_chain; /*!< trusted CAs */ mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) + const int *sig_hashes; /*!< allowed signature hashes */ +#endif + #if defined(MBEDTLS_ECP_C) const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */ #endif @@ -1527,13 +1537,40 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, * controlled by \c mbedtls_ssl_conf_curves() but for CA_int * and CA_root it's \c mbedtls_ssl_conf_cert_profile(). * + * \note This list should be ordered by decreasing preference + * (preferred curve first). + * * \param conf SSL configuration * \param curves Ordered list of allowed curves, * terminated by MBEDTLS_ECP_DP_NONE. */ -void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, const mbedtls_ecp_group_id *curves ); +void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, + const mbedtls_ecp_group_id *curves ); #endif /* MBEDTLS_ECP_C */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) +/** + * \brief Set the allowed hashes for signatures during the handshake. + * (Default: all available hashes.) + * + * \note This only affects which hashes are offered and can be used + * for signatures during the handshake. Hashes for message + * authentication and the TLS PRF are controlled by the + * ciphersuite, see \c mbedtls_ssl_conf_ciphersuites(). Hashes + * used for certificate signature are controlled by the + * verification profile, see \c mbedtls_ssl_conf_cert_profile(). + * + * \note This list should be ordered by decreasing preference + * (preferred hash first). + * + * \param conf SSL configuration + * \param hashes Ordered list of allowed signature hashes, + * terminated by \c MBEDTLS_MD_NONE. + */ +void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, + const int *hashes ); +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */ + #if defined(MBEDTLS_X509_CRT_PARSE_C) /** * \brief Set hostname for ServerName TLS extension diff --git a/library/ssl_cli.c b/library/ssl_cli.c index e4f06864e..40c2d4c86 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1836,9 +1836,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, unsigned char **p, unsigned char *end, @@ -1884,12 +1882,9 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, return( 0 ); } -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 9f241576d..63d2e83a6 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5478,6 +5478,17 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, } #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) +/* + * Set allowed/preferred hashes for handshake signatures + */ +void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, + const int *hashes ) +{ + conf->sig_hashes = hashes; +} +#endif + #if defined(MBEDTLS_ECP_C) /* * Set the allowed elliptic curves @@ -6665,8 +6676,12 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED; #endif +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) + conf->sig_hashes = mbedtls_md_list(); +#endif + #if defined(MBEDTLS_ECP_C) - conf->curve_list = mbedtls_ecp_grp_id_list( ); + conf->curve_list = mbedtls_ecp_grp_id_list(); #endif #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) From 7bfc1227036f0b83f15f252a0529105b9c787c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 14:34:48 +0200 Subject: [PATCH 15/17] Implement sig_hashes --- include/mbedtls/ssl_internal.h | 6 ++++ library/ssl_cli.c | 64 +++++++++++----------------------- library/ssl_srv.c | 2 +- library/ssl_tls.c | 57 ++++++++++++++++++++++++++++-- 4 files changed, 83 insertions(+), 46 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 22b07bc17..391ce5bb8 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -374,11 +374,17 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); #endif mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); +unsigned char mbedtls_ssl_hash_from_md_alg( int md ); #if defined(MBEDTLS_ECP_C) int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); #endif +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) +int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, + mbedtls_md_type_t md ); +#endif + #if defined(MBEDTLS_X509_CRT_PARSE_C) static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl ) { diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 40c2d4c86..e2c2d3fa9 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -156,6 +156,7 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, { unsigned char *p = buf; size_t sig_alg_len = 0; + const int *md; #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) unsigned char *sig_alg_list = buf + 6; #endif @@ -170,55 +171,22 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, /* * Prepare signature_algorithms extension (TLS 1.2) */ -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_SHA512_C) - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA512; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA384; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; -#endif -#if defined(MBEDTLS_SHA256_C) - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA256; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA224; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; -#endif -#if defined(MBEDTLS_SHA1_C) - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA1; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; -#endif -#if defined(MBEDTLS_MD5_C) - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_MD5; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; -#endif -#endif /* MBEDTLS_RSA_C */ + for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) + { #if defined(MBEDTLS_ECDSA_C) -#if defined(MBEDTLS_SHA512_C) - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA512; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA384; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; + sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); + sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; #endif -#if defined(MBEDTLS_SHA256_C) - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA256; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA224; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; +#if defined(MBEDTLS_RSA_C) + sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); + sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; #endif -#if defined(MBEDTLS_SHA1_C) - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA1; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; -#endif -#if defined(MBEDTLS_MD5_C) - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_MD5; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; -#endif -#endif /* MBEDTLS_ECDSA_C */ + } /* * enum { - * none(0), mbedtls_md5(1), mbedtls_sha1(2), sha224(3), mbedtls_sha256(4), sha384(5), - * mbedtls_sha512(6), (255) + * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), + * sha512(6), (255) * } HashAlgorithm; * * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } @@ -1876,6 +1844,16 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } + /* + * Check if the hash is acceptable + */ + if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used HashAlgorithm " + "that was not offered" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) ); *p += 2; diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 554a55239..457362f96 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -211,7 +211,7 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, * * So, just look at the HashAlgorithm part. */ - for( md_cur = mbedtls_md_list(); *md_cur != MBEDTLS_MD_NONE; md_cur++ ) { + for( md_cur = ssl->conf->sig_hashes; *md_cur != MBEDTLS_MD_NONE; md_cur++ ) { for( p = buf + 2; p < end; p += 2 ) { if( *md_cur == (int) mbedtls_ssl_md_alg_from_hash( p[0] ) ) { ssl->handshake->sig_alg = p[0]; diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 63d2e83a6..9007e0540 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6788,7 +6788,7 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) #endif /* MBEDTLS_PK_C */ /* - * Convert between SSL_HASH_XXX and MBEDTLS_MD_XXX + * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX */ mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ) { @@ -6819,9 +6819,41 @@ mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ) } } +/* + * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX + */ +unsigned char mbedtls_ssl_hash_from_md_alg( int md ) +{ + switch( md ) + { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return( MBEDTLS_SSL_HASH_MD5 ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return( MBEDTLS_SSL_HASH_SHA1 ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + return( MBEDTLS_SSL_HASH_SHA224 ); + case MBEDTLS_MD_SHA256: + return( MBEDTLS_SSL_HASH_SHA256 ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + return( MBEDTLS_SSL_HASH_SHA384 ); + case MBEDTLS_MD_SHA512: + return( MBEDTLS_SSL_HASH_SHA512 ); +#endif + default: + return( MBEDTLS_SSL_HASH_NONE ); + } +} + #if defined(MBEDTLS_ECP_C) /* - * Check is a curve proposed by the peer is in our list. + * Check if a curve proposed by the peer is in our list. * Return 0 if we're willing to use it, -1 otherwise. */ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) @@ -6839,6 +6871,27 @@ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_i } #endif /* MBEDTLS_ECP_C */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) +/* + * Check if a hash proposed by the peer is in our list. + * Return 0 if we're willing to use it, -1 otherwise. + */ +int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, + mbedtls_md_type_t md ) +{ + const int *cur; + + if( ssl->conf->sig_hashes == NULL ) + return( -1 ); + + for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) + if( *cur == (int) md ) + return( 0 ); + + return( -1 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */ + #if defined(MBEDTLS_X509_CRT_PARSE_C) int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, const mbedtls_ssl_ciphersuite_t *ciphersuite, From b31c5f68b1d280165980e4345bb075e4aa923b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 13:53:47 +0200 Subject: [PATCH 16/17] Add SSL presets. No need to use a separate profile as in X.509, everything we need is already in ssl_config. Just load appropriate values. --- include/mbedtls/ssl.h | 7 +- library/ssl_tls.c | 145 +++++++++++++++++++-------- programs/ssl/dtls_client.c | 3 +- programs/ssl/dtls_server.c | 3 +- programs/ssl/mini_client.c | 3 +- programs/ssl/ssl_client1.c | 3 +- programs/ssl/ssl_client2.c | 3 +- programs/ssl/ssl_fork_server.c | 3 +- programs/ssl/ssl_mail_client.c | 3 +- programs/ssl/ssl_pthread_server.c | 3 +- programs/ssl/ssl_server.c | 3 +- programs/ssl/ssl_server2.c | 3 +- programs/x509/cert_app.c | 3 +- tests/suites/test_suite_ssl.function | 3 +- 14 files changed, 132 insertions(+), 56 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 49ef310e1..c754b9bb2 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -196,6 +196,9 @@ #define MBEDTLS_SSL_ARC4_ENABLED 0 #define MBEDTLS_SSL_ARC4_DISABLED 1 +#define MBEDTLS_SSL_PRESET_DEFAULT 0 +#define MBEDTLS_SSL_PRESET_SUITEB 2 + /* * Default range for DTLS retransmission timer value, in milliseconds. * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. @@ -2165,6 +2168,8 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ); * \param endpoint MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER * \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS + * \param preset a MBEDTLS_SSL_PRESET_XXX value + * (currently unused). * * \note See \c mbedtls_ssl_conf_transport() for notes on DTLS. * @@ -2172,7 +2177,7 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ); * MBEDTLS_ERR_XXX_ALLOC_FAILED on memory allocation error. */ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, - int endpoint, int transport ); + int endpoint, int transport, int preset ); /** * \brief Free an SSL configuration context diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 9007e0540..48dfd0438 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6612,11 +6612,33 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ) memset( conf, 0, sizeof( mbedtls_ssl_config ) ); } +static int ssl_preset_suiteb_ciphersuites[] = { + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + 0 +}; + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) +static int ssl_preset_suiteb_hashes[] = { + MBEDTLS_MD_SHA256, + MBEDTLS_MD_SHA384, + MBEDTLS_MD_NONE +}; +#endif + +#if defined(MBEDTLS_ECP_C) +static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { + MBEDTLS_ECP_DP_SECP256R1, + MBEDTLS_ECP_DP_SECP384R1, + MBEDTLS_ECP_DP_NONE +}; +#endif + /* * Load default in mbetls_ssl_config */ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, - int endpoint, int transport ) + int endpoint, int transport, int preset ) { #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) int ret; @@ -6627,19 +6649,9 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, mbedtls_ssl_conf_endpoint( conf, endpoint ); mbedtls_ssl_conf_transport( conf, transport ); - conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS 1.0 */ - conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; - conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* DTLS starts with TLS 1.1 */ - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2; - } -#endif - + /* + * Things that are common to all presets + */ #if defined(MBEDTLS_SSL_CLI_C) if( endpoint == MBEDTLS_SSL_IS_CLIENT ) { @@ -6650,16 +6662,6 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, } #endif - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = - mbedtls_ssl_list_ciphersuites(); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - conf->cert_profile = &mbedtls_x509_crt_profile_default; -#endif - #if defined(MBEDTLS_ARC4_C) conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED; #endif @@ -6676,14 +6678,6 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED; #endif -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) - conf->sig_hashes = mbedtls_md_list(); -#endif - -#if defined(MBEDTLS_ECP_C) - conf->curve_list = mbedtls_ecp_grp_id_list(); -#endif - #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) conf->f_cookie_write = ssl_cookie_write_dummy; conf->f_cookie_check = ssl_cookie_check_dummy; @@ -6704,22 +6698,87 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->renego_period[7] = 0x00; #endif -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) - conf->dhm_min_bitlen = 1024; +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) + if( endpoint == MBEDTLS_SSL_IS_SERVER ) + { + if( ( ret = mbedtls_ssl_conf_dh_param( conf, + MBEDTLS_DHM_RFC5114_MODP_2048_P, + MBEDTLS_DHM_RFC5114_MODP_2048_G ) ) != 0 ) + { + return( ret ); + } + } #endif -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - if( endpoint == MBEDTLS_SSL_IS_SERVER ) + /* + * Preset-specific defaults + */ + switch( preset ) { - if( ( ret = mbedtls_ssl_conf_dh_param( conf, - MBEDTLS_DHM_RFC5114_MODP_2048_P, - MBEDTLS_DHM_RFC5114_MODP_2048_G ) ) != 0 ) - { - return( ret ); - } - } + /* + * NSA Suite B + */ + case MBEDTLS_SSL_PRESET_SUITEB: + conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; + conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ + conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; + conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; + + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = + ssl_preset_suiteb_ciphersuites; + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + conf->cert_profile = &mbedtls_x509_crt_profile_suiteb; #endif +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) + conf->sig_hashes = ssl_preset_suiteb_hashes; +#endif + +#if defined(MBEDTLS_ECP_C) + conf->curve_list = ssl_preset_suiteb_curves; +#endif + + /* + * Default + */ + default: + conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; + conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS 1.0 */ + conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; + conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2; +#endif + + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = + mbedtls_ssl_list_ciphersuites(); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + conf->cert_profile = &mbedtls_x509_crt_profile_default; +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) + conf->sig_hashes = mbedtls_md_list(); +#endif + +#if defined(MBEDTLS_ECP_C) + conf->curve_list = mbedtls_ecp_grp_id_list(); +#endif + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) + conf->dhm_min_bitlen = 1024; +#endif + } + return( 0 ); } diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c index 405297556..cc0d051bb 100644 --- a/programs/ssl/dtls_client.c +++ b/programs/ssl/dtls_client.c @@ -163,7 +163,8 @@ int main( int argc, char *argv[] ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ) != 0 ) + MBEDTLS_SSL_TRANSPORT_DATAGRAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c index 4eabf98b6..3ad10ceec 100644 --- a/programs/ssl/dtls_server.c +++ b/programs/ssl/dtls_server.c @@ -199,7 +199,8 @@ int main( void ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_SERVER, - MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ) != 0 ) + MBEDTLS_SSL_TRANSPORT_DATAGRAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c index 090e018bf..2d1dcb9cc 100644 --- a/programs/ssl/mini_client.c +++ b/programs/ssl/mini_client.c @@ -191,7 +191,8 @@ int main( void ) if( mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM) != 0 ) + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) != 0 ) { ret = ssl_config_defaults_failed; goto exit; diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c index 6ff0e142b..b67230514 100644 --- a/programs/ssl/ssl_client1.c +++ b/programs/ssl/ssl_client1.c @@ -153,7 +153,8 @@ int main( void ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 ) + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index eabcbdc64..b8a4a628d 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -1059,7 +1059,8 @@ int main( int argc, char *argv[] ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, - opt.transport ) ) != 0 ) + opt.transport, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret ); goto exit; diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c index 1f50c258d..bafaa01f6 100644 --- a/programs/ssl/ssl_fork_server.c +++ b/programs/ssl/ssl_fork_server.c @@ -177,7 +177,8 @@ int main( void ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_SERVER, - MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 ) + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c index 9587b7a5e..c06d0c06d 100644 --- a/programs/ssl/ssl_mail_client.c +++ b/programs/ssl/ssl_mail_client.c @@ -587,7 +587,8 @@ int main( int argc, char *argv[] ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 ) + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c index 2f414bf52..3af66d045 100644 --- a/programs/ssl/ssl_pthread_server.c +++ b/programs/ssl/ssl_pthread_server.c @@ -412,7 +412,8 @@ int main( void ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_SERVER, - MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 ) + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed: mbedtls_ssl_config_defaults returned -0x%04x\n", -ret ); diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c index 6c837e9a3..f2f969c2d 100644 --- a/programs/ssl/ssl_server.c +++ b/programs/ssl/ssl_server.c @@ -193,7 +193,8 @@ int main( void ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_SERVER, - MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 ) + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 78632a5be..de51d458c 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1533,7 +1533,8 @@ int main( int argc, char *argv[] ) if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_SERVER, - opt.transport ) ) != 0 ) + opt.transport, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret ); goto exit; diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c index 7ae90154d..d93aeba17 100644 --- a/programs/x509/cert_app.c +++ b/programs/x509/cert_app.c @@ -399,7 +399,8 @@ int main( int argc, char *argv[] ) */ if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 ) + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 800f6ac0a..8d3448cbc 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -20,7 +20,8 @@ void ssl_dtls_replay( char *prevs, char *new, int ret ) TEST_ASSERT( mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_DATAGRAM ) == 0 ); + MBEDTLS_SSL_TRANSPORT_DATAGRAM, + MBEDTLS_SSL_PRESET_DEFAULT ) == 0 ); TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 ); /* Read previous record numbers */ From 88d37859b6d1b0ddce970a5d01576e0708b9512e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 17 Jun 2015 14:26:49 +0200 Subject: [PATCH 17/17] Update Changelog for the profiles branch --- ChangeLog | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d995c8a3..8c183a9d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,8 +9,12 @@ Features ability to override the whole module. * New server-side implementation of session tickets that rotate keys to preserve forward secrecy, and allows sharing across multiple contexts. - * Reduced ROM fooprint of SHA-256 and added an option to reduce it even - more (at the expense of performance) MBEDTLS_SHA256_SMALLER. + * Added a concept of X.509 cerificate verification profile that controls + which algorithms and key sizes (curves for ECDSA) are acceptable. + * Expanded configurability of security parameters in the SSL module with + mbedtls_ssl_conf_dhm_min_bitlen() and mbedtls_ssl_conf_sig_hashes(). + * Introduced a concept of presets for SSL security-relevant configuration + parameters. API Changes * All public identifiers moved to the mbedtls_* or MBEDTLS_* namespace. @@ -129,6 +133,8 @@ Default behavior changes enabled in the default configuration, this is only noticeable if using a custom config.h * Default DHM parameters server-side upgraded from 1024 to 2048 bits. + * A minimum RSA key size of 2048 bits is now enforced during ceritificate + chain verification. * Negotiation of truncated HMAC is now disabled by default on server too. * The following functions are now case-sensitive: mbedtls_cipher_info_from_string() @@ -157,6 +163,8 @@ API changes from the 1.4 preview branch Changes * mbedtls_ctr_drbg_random() and mbedtls_hmac_drbg_random() are now thread-safe if MBEDTLS_THREADING_C is enabled. + * Reduced ROM fooprint of SHA-256 and added an option to reduce it even + more (at the expense of performance) MBEDTLS_SHA256_SMALLER. = mbed TLS 1.3 branch