Make truncated hmac a runtime option server-side
Reading the documentation of ssl_set_truncated_hmac() may give the impression
I changed the default for clients but I didn't, the old documentation was
wrong.
diff --git a/ChangeLog b/ChangeLog
index 89c87e0..5643688 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,10 @@
* Add support for Extended Master Secret (draft-ietf-tls-session-hash)
* Add support for Encrypt-then-MAC (RFC 7366)
+Changes
+ * It is now possible to disable neogtiation of truncated HMAC server-side
+ at runtime with ssl_set_truncated_hmac().
+
= PolarSSL 1.3.9 released 2014-10-20
Security
* Lowest common hash was selected from signature_algorithms extension in
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 82ed04e..5849a62 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1487,15 +1487,15 @@
#if defined(POLARSSL_SSL_TRUNCATED_HMAC)
/**
- * \brief Activate negotiation of truncated HMAC (Client only)
- * (Default: SSL_TRUNC_HMAC_ENABLED)
+ * \brief Activate negotiation of truncated HMAC
+ * (Default: SSL_TRUNC_HMAC_DISABLED on client,
+ * SSL_TRUNC_HMAC_ENABLED on server.)
*
* \param ssl SSL context
* \param truncate Enable or disable (SSL_TRUNC_HMAC_ENABLED or
* SSL_TRUNC_HMAC_DISABLED)
*
- * \return O if successful,
- * POLARSSL_ERR_SSL_BAD_INPUT_DATA if used server-side
+ * \return Always 0.
*/
int ssl_set_truncated_hmac( ssl_context *ssl, int truncate );
#endif /* POLARSSL_SSL_TRUNCATED_HMAC */
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 6d8626c..534525a 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -629,7 +629,8 @@
((void) buf);
- ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED;
+ if( ssl->trunc_hmac == SSL_TRUNC_HMAC_ENABLED )
+ ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED;
return( 0 );
}
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index ea34f66..eda3d6d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3782,6 +3782,11 @@
if( endpoint == SSL_IS_CLIENT )
ssl->session_tickets = SSL_SESSION_TICKETS_ENABLED;
#endif
+
+#if defined(POLARSSL_SSL_TRUNCATED_HMAC)
+ if( endpoint == SSL_IS_SERVER )
+ ssl->trunc_hmac = SSL_TRUNC_HMAC_ENABLED;
+#endif
}
void ssl_set_authmode( ssl_context *ssl, int authmode )
@@ -4203,9 +4208,6 @@
#if defined(POLARSSL_SSL_TRUNCATED_HMAC)
int ssl_set_truncated_hmac( ssl_context *ssl, int truncate )
{
- if( ssl->endpoint != SSL_IS_CLIENT )
- return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
-
ssl->trunc_hmac = truncate;
return( 0 );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 08f2ff8..d962d5b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -109,6 +109,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 -1
#define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED
#define DFL_TICKET_TIMEOUT -1
#define DFL_CACHE_MAX -1
@@ -171,6 +172,7 @@
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; /* accept truncated hmac? */
int tickets; /* enable / disable session tickets */
int ticket_timeout; /* session ticket lifetime */
int cache_max; /* max number of session cache entries */
@@ -295,6 +297,13 @@
#define USAGE_MAX_FRAG_LEN ""
#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
+#if defined(POLARSSL_SSL_TRUNCATED_HMAC)
+#define USAGE_TRUNC_HMAC \
+ " trunc_hmac=%%d default: library default\n"
+#else
+#define USAGE_TRUNC_HMAC ""
+#endif
+
#if defined(POLARSSL_SSL_ALPN)
#define USAGE_ALPN \
" alpn=%%s default: \"\" (disabled)\n" \
@@ -341,6 +350,7 @@
USAGE_TICKETS \
USAGE_CACHE \
USAGE_MAX_FRAG_LEN \
+ USAGE_TRUNC_HMAC \
USAGE_ALPN \
USAGE_EMS \
USAGE_ETM \
@@ -726,6 +736,7 @@
opt.max_version = DFL_MAX_VERSION;
opt.auth_mode = DFL_AUTH_MODE;
opt.mfl_code = DFL_MFL_CODE;
+ opt.trunc_hmac = DFL_TRUNC_HMAC;
opt.tickets = DFL_TICKETS;
opt.ticket_timeout = DFL_TICKET_TIMEOUT;
opt.cache_max = DFL_CACHE_MAX;
@@ -902,6 +913,15 @@
{
opt.alpn_string = q;
}
+ else if( strcmp( p, "trunc_hmac" ) == 0 )
+ {
+ switch( atoi( q ) )
+ {
+ case 0: opt.trunc_hmac = SSL_TRUNC_HMAC_DISABLED; break;
+ case 1: opt.trunc_hmac = SSL_TRUNC_HMAC_ENABLED; break;
+ default: goto usage;
+ }
+ }
else if( strcmp( p, "extended_ms" ) == 0 )
{
switch( atoi( q ) )
@@ -1297,6 +1317,11 @@
};
#endif
+#if defined(POLARSSL_SSL_TRUNCATED_HMAC)
+ if( opt.trunc_hmac != DFL_TRUNC_HMAC )
+ ssl_set_truncated_hmac( &ssl, opt.trunc_hmac );
+#endif
+
#if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET)
if( opt.extended_ms != DFL_EXTENDED_MS )
ssl_set_extended_master_secret( &ssl, opt.extended_ms );
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 1349737..e4dc7ea 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -428,16 +428,43 @@
# Tests for Truncated HMAC extension
-run_test "Truncated HMAC: reference" \
+run_test "Truncated HMAC: client default, server default" \
"$P_SRV debug_level=4" \
- "$P_CLI trunc_hmac=0 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
0 \
- -s "dumping 'computed mac' (20 bytes)"
+ -s "dumping 'computed mac' (20 bytes)" \
+ -S "dumping 'computed mac' (10 bytes)"
-run_test "Truncated HMAC: actual test" \
+run_test "Truncated HMAC: client disabled, server default" \
"$P_SRV debug_level=4" \
- "$P_CLI trunc_hmac=1 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
+ trunc_hmac=0" \
0 \
+ -s "dumping 'computed mac' (20 bytes)" \
+ -S "dumping 'computed mac' (10 bytes)"
+
+run_test "Truncated HMAC: client enabled, server default" \
+ "$P_SRV debug_level=4" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
+ trunc_hmac=1" \
+ 0 \
+ -S "dumping 'computed mac' (20 bytes)" \
+ -s "dumping 'computed mac' (10 bytes)"
+
+run_test "Truncated HMAC: client enabled, server disabled" \
+ "$P_SRV debug_level=4 trunc_hmac=0" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
+ trunc_hmac=1" \
+ 0 \
+ -s "dumping 'computed mac' (20 bytes)" \
+ -S "dumping 'computed mac' (10 bytes)"
+
+run_test "Truncated HMAC: client enabled, server enabled" \
+ "$P_SRV debug_level=4 trunc_hmac=1" \
+ "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
+ trunc_hmac=1" \
+ 0 \
+ -S "dumping 'computed mac' (20 bytes)" \
-s "dumping 'computed mac' (10 bytes)"
# Tests for Encrypt-then-MAC extension