diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 4fd116e81..f08fc89a5 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -337,6 +337,41 @@ #define MBEDTLS_SSL_SIG_RSA 1 #define MBEDTLS_SSL_SIG_ECDSA 3 +/* + * TLS 1.3 signature algorithms + * RFC 8446, Section 4.2.2 + */ + +/* RSASSA-PKCS1-v1_5 algorithms */ +#define MBEDTLS_TLS13_SIG_RSA_PKCS1_SHA256 0x0401 +#define MBEDTLS_TLS13_SIG_RSA_PKCS1_SHA384 0x0501 +#define MBEDTLS_TLS13_SIG_RSA_PKCS1_SHA512 0x0601 + +/* ECDSA algorithms */ +#define MBEDTLS_TLS13_SIG_ECDSA_SECP256R1_SHA256 0x0403 +#define MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384 0x0503 +#define MBEDTLS_TLS13_SIG_ECDSA_SECP521R1_SHA512 0x0603 + +/* RSASSA-PSS algorithms with public key OID rsaEncryption */ +#define MBEDTLS_TLS13_SIG_RSA_PSS_RSAE_SHA256 0x0804 +#define MBEDTLS_TLS13_SIG_RSA_PSS_RSAE_SHA384 0x0805 +#define MBEDTLS_TLS13_SIG_RSA_PSS_RSAE_SHA512 0x0806 + +/* EdDSA algorithms */ +#define MBEDTLS_TLS13_SIG_ED25519 0x0807 +#define MBEDTLS_TLS13_SIG_ED448 0x0808 + +/* RSASSA-PSS algorithms with public key OID RSASSA-PSS */ +#define MBEDTLS_TLS13_SIG_RSA_PSS_PSS_SHA256 0x0809 +#define MBEDTLS_TLS13_SIG_RSA_PSS_PSS_SHA384 0x080A +#define MBEDTLS_TLS13_SIG_RSA_PSS_PSS_SHA512 0x080B + +/* LEGACY ALGORITHMS */ +#define MBEDTLS_TLS13_SIG_RSA_PKCS1_SHA1 0x0201 +#define MBEDTLS_TLS13_SIG_ECDSA_SHA1 0x0203 + +#define MBEDTLS_TLS13_SIG_NONE 0x0 + /* * Client Certificate Types * RFC 5246 section 7.4.4 plus RFC 4492 section 5.5 @@ -1154,6 +1189,10 @@ struct mbedtls_ssl_config #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) const int *MBEDTLS_PRIVATE(sig_hashes); /*!< allowed signature hashes */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + const uint16_t *MBEDTLS_PRIVATE(tls13_sig_algs); /*!< allowed signature algorithms for TLS 1.3 */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif #if defined(MBEDTLS_ECP_C) @@ -3012,6 +3051,20 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, */ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, const int *hashes ); + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) +/** + * \brief Configure allowed signature algorithms for use in TLS 1.3 + * + * \param conf The SSL configuration to use. + * \param sig_algs List of allowed IANA values for TLS 1.3 signature algorithms, + * terminated by \c MBEDTLS_TLS13_SIG_NONE. The list must remain + * available throughout the lifetime of the conf object. Supported + * values are available as \c MBEDTLS_TLS13_SIG_XXXX + */ +void mbedtls_ssl_conf_sig_algs( mbedtls_ssl_config *conf, + const uint16_t* sig_algs ); +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_X509_CRT_PARSE_C) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index cd75ec040..f8cad4aec 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3937,6 +3937,15 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, { conf->sig_hashes = hashes; } + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) +/* Configure allowed signature algorithms for use in TLS 1.3 */ +void mbedtls_ssl_conf_sig_algs( mbedtls_ssl_config *conf, + const uint16_t* sig_algs ) +{ + conf->tls13_sig_algs = sig_algs; +} +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_ECP_C) @@ -6305,6 +6314,37 @@ static int ssl_preset_suiteb_hashes[] = { MBEDTLS_MD_SHA384, MBEDTLS_MD_NONE }; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) +static uint16_t ssl_preset_default_sig_algs[] = { + /* ECDSA algorithms */ +#if defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + MBEDTLS_TLS13_SIG_ECDSA_SECP256R1_SHA256, +#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */ +#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384, +#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */ +#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + MBEDTLS_TLS13_SIG_ECDSA_SECP521R1_SHA512, +#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */ +#endif /* MBEDTLS_ECDSA_C */ + MBEDTLS_TLS13_SIG_NONE +}; + +static uint16_t ssl_preset_suiteb_sig_algs[] = { + /* ECDSA algorithms */ +#if defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + MBEDTLS_TLS13_SIG_ECDSA_SECP256R1_SHA256, +#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */ +#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384, +#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */ +#endif /* MBEDTLS_ECDSA_C */ + MBEDTLS_TLS13_SIG_NONE +}; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif #if defined(MBEDTLS_ECP_C) @@ -6419,6 +6459,9 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) conf->sig_hashes = ssl_preset_suiteb_hashes; +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + conf->tls13_sig_algs = ssl_preset_suiteb_sig_algs; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif #if defined(MBEDTLS_ECP_C) @@ -6453,7 +6496,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) conf->sig_hashes = ssl_preset_default_hashes; -#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + conf->tls13_sig_algs = ssl_preset_default_sig_algs; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_ECP_C) conf->curve_list = ssl_preset_default_curves; diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 86c314c35..1400961b8 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -88,6 +88,7 @@ int main( void ) #define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED #define DFL_ALPN_STRING NULL #define DFL_CURVES NULL +#define DFL_SIG_ALGS NULL #define DFL_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM #define DFL_HS_TO_MIN 0 #define DFL_HS_TO_MAX 0 @@ -269,6 +270,15 @@ int main( void ) #define USAGE_CURVES "" #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) +#define USAGE_SIG_ALGS \ + " sig_algs=a,b,c,d default: \"default\" (library default)\n" \ + " example: \"ecdsa_secp256r1_sha256,ecdsa_secp384r1_sha384\"\n" +#else +#define USAGE_SIG_ALGS "" +#endif + #if defined(MBEDTLS_SSL_PROTO_DTLS) #define USAGE_DTLS \ " dtls=%%d default: 0 (TLS)\n" \ @@ -393,6 +403,7 @@ int main( void ) USAGE_ETM \ USAGE_REPRODUCIBLE \ USAGE_CURVES \ + USAGE_SIG_ALGS \ USAGE_DHMLEN \ "\n" @@ -417,9 +428,9 @@ int main( void ) USAGE_SERIALIZATION \ " acceptable ciphersuite names:\n" -#define ALPN_LIST_SIZE 10 -#define CURVE_LIST_SIZE 20 - +#define ALPN_LIST_SIZE 10 +#define CURVE_LIST_SIZE 20 +#define SIG_ALG_LIST_SIZE 5 /* * global options @@ -472,6 +483,7 @@ struct options int reconnect_hard; /* unexpectedly reconnect from the same port */ int tickets; /* enable / disable session tickets */ const char *curves; /* list of supported elliptic curves */ + const char *sig_algs; /* supported TLS 1.3 signature algorithms */ const char *alpn_string; /* ALPN supported protocols */ int transport; /* TLS or DTLS? */ uint32_t hs_to_min; /* Initial value of DTLS handshake timer */ @@ -631,6 +643,12 @@ int main( int argc, char *argv[] ) mbedtls_net_context server_fd; io_ctx_t io_ctx; +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + uint16_t sig_alg_list[SIG_ALG_LIST_SIZE]; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ + unsigned char buf[MAX_REQUEST_SIZE + 1]; #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) @@ -833,6 +851,7 @@ int main( int argc, char *argv[] ) opt.tickets = DFL_TICKETS; opt.alpn_string = DFL_ALPN_STRING; opt.curves = DFL_CURVES; + opt.sig_algs = DFL_SIG_ALGS; opt.transport = DFL_TRANSPORT; opt.hs_to_min = DFL_HS_TO_MIN; opt.hs_to_max = DFL_HS_TO_MAX; @@ -1063,6 +1082,12 @@ int main( int argc, char *argv[] ) } else if( strcmp( p, "curves" ) == 0 ) opt.curves = q; +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + else if( strcmp( p, "sig_algs" ) == 0 ) + opt.sig_algs = q; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ else if( strcmp( p, "etm" ) == 0 ) { switch( atoi( q ) ) @@ -1450,6 +1475,60 @@ int main( int argc, char *argv[] ) } #endif /* MBEDTLS_ECP_C */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + if( opt.sig_algs != NULL ) + { + p = (char *) opt.sig_algs; + i = 0; + + /* Leave room for a final MBEDTLS_TLS13_SIG_NONE in signature algorithm list (sig_alg_list). */ + while( i < SIG_ALG_LIST_SIZE - 1 && *p != '\0' ) + { + q = p; + + /* Terminate the current string */ + while( *p != ',' && *p != '\0' ) + p++; + if( *p == ',' ) + *p++ = '\0'; + + if( strcmp( q, "ecdsa_secp256r1_sha256" ) == 0 ) + { + sig_alg_list[i++] = MBEDTLS_TLS13_SIG_ECDSA_SECP256R1_SHA256; + } + else if( strcmp( q, "ecdsa_secp384r1_sha384" ) == 0 ) + { + sig_alg_list[i++] = MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384; + } + else if( strcmp( q, "ecdsa_secp521r1_sha512" ) == 0 ) + { + sig_alg_list[i++] = MBEDTLS_TLS13_SIG_ECDSA_SECP521R1_SHA512; + } + else + { + mbedtls_printf( "unknown signature algorithm %s\n", q ); + mbedtls_printf( "supported signature algorithms: " ); + mbedtls_printf( "ecdsa_secp256r1_sha256 " ); + mbedtls_printf( "ecdsa_secp384r1_sha384 " ); + mbedtls_printf( "ecdsa_secp521r1_sha512 " ); + mbedtls_printf( "\n" ); + goto exit; + } + } + + if( i == ( SIG_ALG_LIST_SIZE - 1 ) && *p != '\0' ) + { + mbedtls_printf( "signature algorithm list too long, maximum %d", + SIG_ALG_LIST_SIZE - 1 ); + goto exit; + } + + sig_alg_list[i] = MBEDTLS_TLS13_SIG_NONE; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ + #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) { @@ -1785,6 +1864,11 @@ int main( int argc, char *argv[] ) } #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( opt.sig_algs != NULL ) + mbedtls_ssl_conf_sig_algs( &conf, sig_alg_list ); +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) #if defined(MBEDTLS_USE_PSA_CRYPTO) if( opt.psk_opaque != 0 ) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 83bd617c6..b9a789e72 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -119,6 +119,7 @@ int main( void ) #define DFL_SNI NULL #define DFL_ALPN_STRING NULL #define DFL_CURVES NULL +#define DFL_SIG_ALGS NULL #define DFL_DHM_FILE NULL #define DFL_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM #define DFL_COOKIES 1 @@ -418,6 +419,15 @@ int main( void ) #define USAGE_CURVES "" #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) +#define USAGE_SIG_ALGS \ + " sig_algs=a,b,c,d default: \"default\" (library default)\n" \ + " example: \"ecdsa_secp256r1_sha256,ecdsa_secp384r1_sha384\"\n" +#else +#define USAGE_SIG_ALGS "" +#endif + #if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) #define USAGE_SERIALIZATION \ " serialize=%%d default: 0 (do not serialize/deserialize)\n" \ @@ -484,6 +494,7 @@ int main( void ) USAGE_EMS \ USAGE_ETM \ USAGE_CURVES \ + USAGE_SIG_ALGS \ "\n" #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) @@ -509,8 +520,9 @@ int main( void ) USAGE_SERIALIZATION \ " acceptable ciphersuite names:\n" -#define ALPN_LIST_SIZE 10 -#define CURVE_LIST_SIZE 20 +#define ALPN_LIST_SIZE 10 +#define CURVE_LIST_SIZE 20 +#define SIG_ALG_LIST_SIZE 5 #define PUT_UINT64_BE(out_be,in_le,i) \ { \ @@ -583,6 +595,7 @@ struct options int cache_timeout; /* expiration delay of session cache entries */ char *sni; /* string describing sni information */ const char *curves; /* list of supported elliptic curves */ + const char *sig_algs; /* supported TLS 1.3 signature algorithms */ const char *alpn_string; /* ALPN supported protocols */ const char *dhm_file; /* the file with the DH parameters */ int extended_ms; /* allow negotiation of extended MS? */ @@ -1326,6 +1339,12 @@ int main( int argc, char *argv[] ) size_t context_buf_len = 0; #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + uint16_t sig_alg_list[SIG_ALG_LIST_SIZE]; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ + int i; char *p, *q; const int *list; @@ -1498,6 +1517,7 @@ int main( int argc, char *argv[] ) opt.sni = DFL_SNI; opt.alpn_string = DFL_ALPN_STRING; opt.curves = DFL_CURVES; + opt.sig_algs = DFL_SIG_ALGS; opt.dhm_file = DFL_DHM_FILE; opt.transport = DFL_TRANSPORT; opt.cookies = DFL_COOKIES; @@ -1665,6 +1685,12 @@ int main( int argc, char *argv[] ) } else if( strcmp( p, "curves" ) == 0 ) opt.curves = q; +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + else if( strcmp( p, "sig_algs" ) == 0 ) + opt.sig_algs = q; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && && \ + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ else if( strcmp( p, "renegotiation" ) == 0 ) { opt.renegotiation = (atoi( q )) ? @@ -2172,6 +2198,60 @@ int main( int argc, char *argv[] ) } #endif /* MBEDTLS_ECP_C */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + if( opt.sig_algs != NULL ) + { + p = (char *) opt.sig_algs; + i = 0; + + /* Leave room for a final MBEDTLS_TLS13_SIG_NONE in signature algorithm list (sig_alg_list). */ + while( i < SIG_ALG_LIST_SIZE - 1 && *p != '\0' ) + { + q = p; + + /* Terminate the current string */ + while( *p != ',' && *p != '\0' ) + p++; + if( *p == ',' ) + *p++ = '\0'; + + if( strcmp( q, "ecdsa_secp256r1_sha256" ) == 0 ) + { + sig_alg_list[i++] = MBEDTLS_TLS13_SIG_ECDSA_SECP256R1_SHA256; + } + else if( strcmp( q, "ecdsa_secp384r1_sha384" ) == 0 ) + { + sig_alg_list[i++] = MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384; + } + else if( strcmp( q, "ecdsa_secp521r1_sha512" ) == 0 ) + { + sig_alg_list[i++] = MBEDTLS_TLS13_SIG_ECDSA_SECP521R1_SHA512; + } + else + { + mbedtls_printf( "unknown signature algorithm %s\n", q ); + mbedtls_printf( "supported signature algorithms: " ); + mbedtls_printf( "ecdsa_secp256r1_sha256 " ); + mbedtls_printf( "ecdsa_secp384r1_sha384 " ); + mbedtls_printf( "ecdsa_secp521r1_sha512 " ); + mbedtls_printf( "\n" ); + goto exit; + } + } + + if( i == ( SIG_ALG_LIST_SIZE - 1 ) && *p != '\0' ) + { + mbedtls_printf( "signature algorithm list too long, maximum %d", + SIG_ALG_LIST_SIZE - 1 ); + goto exit; + } + + sig_alg_list[i] = MBEDTLS_TLS13_SIG_NONE; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ + #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) { @@ -2750,6 +2830,11 @@ int main( int argc, char *argv[] ) } #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if( opt.sig_algs != NULL ) + mbedtls_ssl_conf_sig_algs( &conf, sig_alg_list ); +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) if( strlen( opt.psk ) != 0 && strlen( opt.psk_identity ) != 0 )