diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 4e1d25a83..1403ab331 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -148,6 +148,9 @@ #define SSL_LEGACY_ALLOW_RENEGOTIATION 1 #define SSL_LEGACY_BREAK_HANDSHAKE 2 +#define SSL_TRUNC_HMAC_DISABLED 0 +#define SSL_TRUNC_HMAC_ENABLED 1 + /* * Size of the input / output buffer. * Note: the RFC defines the default size of SSL / TLS messages. If you @@ -540,6 +543,7 @@ struct _ssl_context int disable_renegotiation; /*!< enable/disable renegotiation */ int allow_legacy_renegotiation; /*!< allow legacy renegotiation */ const int *ciphersuite_list[4]; /*!< allowed ciphersuites / version */ + int trunc_hmac; /*!< negotiate truncated hmac? */ #if defined(POLARSSL_DHM_C) mpi dhm_P; /*!< prime modulus for DHM */ @@ -976,6 +980,16 @@ void ssl_set_min_version( ssl_context *ssl, int major, int minor ); */ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ); +/** + * \brief Activate negotiation of truncated HMAC (Client only) + * + * \param ssl SSL context + * + * \return O if successful, + * POLARSSL_ERR_SSL_BAD_INPUT_DATA if used server-side + */ +int ssl_set_truncated_hmac( ssl_context *ssl ); + /** * \brief Enable / Disable renegotiation support for connection when * initiated by peer diff --git a/library/ssl_tls.c b/library/ssl_tls.c index f701a8a1f..4e7cac79b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3141,6 +3141,16 @@ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ) return( 0 ); } +int ssl_set_truncated_hmac( ssl_context *ssl ) +{ + if( ssl->endpoint != SSL_IS_CLIENT ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + ssl->trunc_hmac = SSL_TRUNC_HMAC_ENABLED; + + return( 0 ); +} + void ssl_set_renegotiation( ssl_context *ssl, int renegotiation ) { ssl->disable_renegotiation = renegotiation; diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 56d0e9112..60e6f7e97 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -58,6 +58,7 @@ #define DFL_MAX_VERSION -1 #define DFL_AUTH_MODE SSL_VERIFY_OPTIONAL #define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE +#define DFL_TRUNC_HMAC 0 #define LONG_HEADER "User-agent: blah-blah-blah-blah-blah-blah-blah-blah-" \ "-01--blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-" \ @@ -94,6 +95,7 @@ struct options int max_version; /* maximum protocol version accepted */ int auth_mode; /* verify mode for connection */ unsigned char mfl_code; /* code for maximum fragment length */ + int trunc_hmac; /* negotiate truncated hmac or not */ } opt; static void my_debug( void *ctx, int level, const char *str ) @@ -191,6 +193,7 @@ static int my_verify( void *data, x509_cert *crt, int depth, int *flags ) " options: none, optional, required\n" \ " max_frag_len=%%d default: 16384 (tls default)" \ " options: 512, 1024, 2048, 4096" \ + " trunc_hmac=%%d default: 0 (disabled)\n" \ USAGE_PSK \ "\n" \ " force_ciphersuite= default: all enabled\n"\ @@ -281,6 +284,7 @@ int main( int argc, char *argv[] ) opt.max_version = DFL_MAX_VERSION; opt.auth_mode = DFL_AUTH_MODE; opt.mfl_code = DFL_MFL_CODE; + opt.trunc_hmac = DFL_TRUNC_HMAC; for( i = 1; i < argc; i++ ) { @@ -416,6 +420,12 @@ int main( int argc, char *argv[] ) else goto usage; } + else if( strcmp( p, "trunc_hmac" ) == 0 ) + { + opt.trunc_hmac = atoi( q ); + if( opt.trunc_hmac < 0 || opt.trunc_hmac > 1 ) + goto usage; + } else goto usage; } @@ -623,6 +633,9 @@ int main( int argc, char *argv[] ) ssl_set_max_frag_len( &ssl, opt.mfl_code ); + if( opt.trunc_hmac != 0 ) + ssl_set_truncated_hmac( &ssl ); + ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg ); ssl_set_dbg( &ssl, my_debug, stdout ); ssl_set_bio( &ssl, net_recv, &server_fd,