mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-23 04:15:35 +00:00
Merge support for 1/n-1 record splitting
This commit is contained in:
commit
f3561154ff
|
@ -28,6 +28,7 @@ Features
|
|||
* Add compile-time option POLARSSL_X509_MAX_INTERMEDIATE_CA to limit the
|
||||
length of an X.509 verification chain.
|
||||
* Support for renegotiation can now be disabled at compile-time
|
||||
* Support for 1/n-1 record splitting, a countermeasure against BEAST.
|
||||
|
||||
Bugfix
|
||||
* Stack buffer overflow if ctr_drbg_update() is called with too large
|
||||
|
|
|
@ -277,6 +277,11 @@
|
|||
#error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING) && \
|
||||
!defined(POLARSSL_SSL_PROTO_SSL3) && !defined(POLARSSL_SSL_PROTO_TLS1)
|
||||
#error "POLARSSL_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) && \
|
||||
!defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
#error "POLARSSL_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
|
||||
|
|
|
@ -886,6 +886,18 @@
|
|||
*/
|
||||
//#define POLARSSL_SSL_HW_RECORD_ACCEL
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_CBC_RECORD_SPLITTING
|
||||
*
|
||||
* Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0.
|
||||
*
|
||||
* This is a countermeasure to the BEAST attack, which also minimizes the risk
|
||||
* of interoperability issues compared to sending 0-length records.
|
||||
*
|
||||
* Comment this macro to disable 1/n-1 record splitting.
|
||||
*/
|
||||
#define POLARSSL_SSL_CBC_RECORD_SPLITTING
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_DISABLE_RENEGOTIATION
|
||||
*
|
||||
|
|
|
@ -253,6 +253,9 @@
|
|||
#define SSL_SESSION_TICKETS_DISABLED 0
|
||||
#define SSL_SESSION_TICKETS_ENABLED 1
|
||||
|
||||
#define SSL_CBC_RECORD_SPLITTING_DISABLED -1
|
||||
#define SSL_CBC_RECORD_SPLITTING_ENABLED 0
|
||||
|
||||
/**
|
||||
* \name SECTION: Module settings
|
||||
*
|
||||
|
@ -832,6 +835,10 @@ struct _ssl_context
|
|||
#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
|
||||
unsigned char mfl_code; /*!< MaxFragmentLength chosen by us */
|
||||
#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
|
||||
char split_done; /*!< flag for record splitting:
|
||||
-1 disabled, 0 todo, 1 done */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PKI layer
|
||||
|
@ -1528,6 +1535,21 @@ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code );
|
|||
int ssl_set_truncated_hmac( ssl_context *ssl, int truncate );
|
||||
#endif /* POLARSSL_SSL_TRUNCATED_HMAC */
|
||||
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
|
||||
/**
|
||||
* \brief Enable / Disable 1/n-1 record splitting
|
||||
* (Default: SSL_CBC_RECORD_SPLITTING_ENABLED)
|
||||
*
|
||||
* \note Only affects SSLv3 and TLS 1.0, not higher versions.
|
||||
* Does not affect non-CBC ciphersuites in any version.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param split SSL_CBC_RECORD_SPLITTING_ENABLED or
|
||||
* SSL_CBC_RECORD_SPLITTING_DISABLED
|
||||
*/
|
||||
void ssl_set_cbc_record_splitting( ssl_context *ssl, char split );
|
||||
#endif /* POLARSSL_SSL_CBC_RECORD_SPLITTING */
|
||||
|
||||
#if defined(POLARSSL_SSL_SESSION_TICKETS)
|
||||
/**
|
||||
* \brief Enable / Disable session tickets
|
||||
|
@ -1796,6 +1818,10 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len );
|
|||
* \note When this function returns POLARSSL_ERR_NET_WANT_WRITE,
|
||||
* it must be called later with the *same* arguments,
|
||||
* until it returns a positive value.
|
||||
*
|
||||
* \note This function may write less than the number of bytes
|
||||
* requested if len is greater than the maximum record length.
|
||||
* For arbitrary-sized messages, it should be called in a loop.
|
||||
*/
|
||||
int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len );
|
||||
|
||||
|
|
|
@ -3717,6 +3717,10 @@ int ssl_session_reset( ssl_context *ssl )
|
|||
ssl->out_msgtype = 0;
|
||||
ssl->out_msglen = 0;
|
||||
ssl->out_left = 0;
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
|
||||
if( ssl->split_done != SSL_CBC_RECORD_SPLITTING_DISABLED )
|
||||
ssl->split_done = 0;
|
||||
#endif
|
||||
|
||||
ssl->transform_in = NULL;
|
||||
ssl->transform_out = NULL;
|
||||
|
@ -4263,6 +4267,13 @@ int ssl_set_truncated_hmac( ssl_context *ssl, int truncate )
|
|||
}
|
||||
#endif /* POLARSSL_SSL_TRUNCATED_HMAC */
|
||||
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
|
||||
void ssl_set_cbc_record_splitting( ssl_context *ssl, char split )
|
||||
{
|
||||
ssl->split_done = split;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy )
|
||||
{
|
||||
ssl->allow_legacy_renegotiation = allow_legacy;
|
||||
|
@ -4741,7 +4752,11 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
|
|||
/*
|
||||
* Send application data to be encrypted by the SSL layer
|
||||
*/
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
|
||||
static int ssl_write_real( ssl_context *ssl, const unsigned char *buf, size_t len )
|
||||
#else
|
||||
int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
size_t n;
|
||||
|
@ -4810,6 +4825,45 @@ int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
|
|||
return( (int) n );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write application data, doing 1/n-1 splitting if necessary.
|
||||
*
|
||||
* With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
|
||||
* then the caller will call us again with the same arguments, so
|
||||
* remember wether we already did the split or not.
|
||||
*/
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
|
||||
int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ssl->split_done == SSL_CBC_RECORD_SPLITTING_DISABLED ||
|
||||
len <= 1 ||
|
||||
ssl->minor_ver > SSL_MINOR_VERSION_1 ||
|
||||
cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
|
||||
!= POLARSSL_MODE_CBC )
|
||||
{
|
||||
return( ssl_write_real( ssl, buf, len ) );
|
||||
}
|
||||
|
||||
if( ssl->split_done == 0 )
|
||||
{
|
||||
ssl->split_done = 1;
|
||||
if( ( ret = ssl_write_real( ssl, buf, 1 ) ) < 0 )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ssl->split_done == 1 )
|
||||
{
|
||||
ssl->split_done = 0;
|
||||
if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) < 0 )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( ret + 1 );
|
||||
}
|
||||
#endif /* POLARSSL_SSL_CBC_RECORD_SPLITTING */
|
||||
|
||||
/*
|
||||
* Notify the peer that the connection is being closed
|
||||
*/
|
||||
|
|
|
@ -91,6 +91,7 @@ int main( int argc, char *argv[] )
|
|||
#define DFL_AUTH_MODE SSL_VERIFY_REQUIRED
|
||||
#define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE
|
||||
#define DFL_TRUNC_HMAC 0
|
||||
#define DFL_RECSPLIT -1
|
||||
#define DFL_RECONNECT 0
|
||||
#define DFL_RECO_DELAY 0
|
||||
#define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED
|
||||
|
@ -131,6 +132,7 @@ struct options
|
|||
int auth_mode; /* verify mode for connection */
|
||||
unsigned char mfl_code; /* code for maximum fragment length */
|
||||
int trunc_hmac; /* negotiate truncated hmac or not */
|
||||
int recsplit; /* enable record splitting? */
|
||||
int reconnect; /* attempt to resume session */
|
||||
int reco_delay; /* delay in seconds before resuming session */
|
||||
int tickets; /* enable / disable session tickets */
|
||||
|
@ -275,6 +277,13 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
|
|||
#define USAGE_MAX_FRAG_LEN ""
|
||||
#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
|
||||
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
|
||||
#define USAGE_RECSPLIT \
|
||||
" recplit=%%d default: (library default)\n"
|
||||
#else
|
||||
#define USAGE_RECSPLIT
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_TIMING_C)
|
||||
#define USAGE_TIME \
|
||||
" reco_delay=%%d default: 0 seconds\n"
|
||||
|
@ -350,6 +359,7 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
|
|||
USAGE_FALLBACK \
|
||||
USAGE_EMS \
|
||||
USAGE_ETM \
|
||||
USAGE_RECSPLIT \
|
||||
"\n" \
|
||||
" min_version=%%s default: \"\" (ssl3)\n" \
|
||||
" max_version=%%s default: \"\" (tls1_2)\n" \
|
||||
|
@ -446,6 +456,7 @@ int main( int argc, char *argv[] )
|
|||
opt.auth_mode = DFL_AUTH_MODE;
|
||||
opt.mfl_code = DFL_MFL_CODE;
|
||||
opt.trunc_hmac = DFL_TRUNC_HMAC;
|
||||
opt.recsplit = DFL_RECSPLIT;
|
||||
opt.reconnect = DFL_RECONNECT;
|
||||
opt.reco_delay = DFL_RECO_DELAY;
|
||||
opt.tickets = DFL_TICKETS;
|
||||
|
@ -671,6 +682,12 @@ int main( int argc, char *argv[] )
|
|||
if( opt.trunc_hmac < 0 || opt.trunc_hmac > 1 )
|
||||
goto usage;
|
||||
}
|
||||
else if( strcmp( p, "recsplit" ) == 0 )
|
||||
{
|
||||
opt.recsplit = atoi( q );
|
||||
if( opt.recsplit < 0 || opt.recsplit > 1 )
|
||||
goto usage;
|
||||
}
|
||||
else
|
||||
goto usage;
|
||||
}
|
||||
|
@ -963,6 +980,13 @@ int main( int argc, char *argv[] )
|
|||
ssl_set_encrypt_then_mac( &ssl, opt.etm );
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
|
||||
if( opt.recsplit != DFL_RECSPLIT )
|
||||
ssl_set_cbc_record_splitting( &ssl, opt.recsplit
|
||||
? SSL_CBC_RECORD_SPLITTING_ENABLED
|
||||
: SSL_CBC_RECORD_SPLITTING_DISABLED );
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SSL_ALPN)
|
||||
if( opt.alpn_string != NULL )
|
||||
if( ( ret = ssl_set_alpn_protocols( &ssl, alpn_list ) ) != 0 )
|
||||
|
|
|
@ -662,6 +662,62 @@ run_test "Fallback SCSV: enabled, max version, openssl client" \
|
|||
-s "received FALLBACK_SCSV" \
|
||||
-S "inapropriate fallback"
|
||||
|
||||
# Tests for CBC 1/n-1 record splitting
|
||||
|
||||
run_test "CBC Record splitting: TLS 1.2, no splitting" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
|
||||
request_size=123 force_version=tls1_2" \
|
||||
0 \
|
||||
-s "Read from client: 123 bytes read" \
|
||||
-S "Read from client: 1 bytes read" \
|
||||
-S "122 bytes read"
|
||||
|
||||
run_test "CBC Record splitting: TLS 1.1, no splitting" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
|
||||
request_size=123 force_version=tls1_1" \
|
||||
0 \
|
||||
-s "Read from client: 123 bytes read" \
|
||||
-S "Read from client: 1 bytes read" \
|
||||
-S "122 bytes read"
|
||||
|
||||
run_test "CBC Record splitting: TLS 1.0, splitting" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
|
||||
request_size=123 force_version=tls1" \
|
||||
0 \
|
||||
-S "Read from client: 123 bytes read" \
|
||||
-s "Read from client: 1 bytes read" \
|
||||
-s "122 bytes read"
|
||||
|
||||
run_test "CBC Record splitting: SSLv3, splitting" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
|
||||
request_size=123 force_version=ssl3" \
|
||||
0 \
|
||||
-S "Read from client: 123 bytes read" \
|
||||
-s "Read from client: 1 bytes read" \
|
||||
-s "122 bytes read"
|
||||
|
||||
run_test "CBC Record splitting: TLS 1.0 RC4, no splitting" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-RC4-128-SHA \
|
||||
request_size=123 force_version=tls1" \
|
||||
0 \
|
||||
-s "Read from client: 123 bytes read" \
|
||||
-S "Read from client: 1 bytes read" \
|
||||
-S "122 bytes read"
|
||||
|
||||
run_test "CBC Record splitting: TLS 1.0, splitting disabled" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
|
||||
request_size=123 force_version=tls1 recsplit=0" \
|
||||
0 \
|
||||
-s "Read from client: 123 bytes read" \
|
||||
-S "Read from client: 1 bytes read" \
|
||||
-S "122 bytes read"
|
||||
|
||||
# Tests for Session Tickets
|
||||
|
||||
run_test "Session resume using tickets: basic" \
|
||||
|
@ -2087,7 +2143,8 @@ run_test "Small packet TLS 1.2 BlockCipher without EtM" \
|
|||
|
||||
run_test "Small packet TLS 1.2 BlockCipher larger MAC" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI request_size=1 force_version=tls1_2 force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384" \
|
||||
"$P_CLI request_size=1 force_version=tls1_2 \
|
||||
force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384" \
|
||||
0 \
|
||||
-s "Read from client: 1 bytes read"
|
||||
|
||||
|
@ -2132,7 +2189,7 @@ run_test "Small packet TLS 1.2 AEAD shorter tag" \
|
|||
|
||||
run_test "Large packet SSLv3 BlockCipher" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI request_size=16384 force_version=ssl3 \
|
||||
"$P_CLI request_size=16384 force_version=ssl3 recsplit=0 \
|
||||
force_ciphersuite=TLS-RSA-WITH-AES-256-CBC-SHA" \
|
||||
0 \
|
||||
-s "Read from client: 16384 bytes read"
|
||||
|
@ -2146,14 +2203,14 @@ run_test "Large packet SSLv3 StreamCipher" \
|
|||
|
||||
run_test "Large packet TLS 1.0 BlockCipher" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI request_size=16384 force_version=tls1 \
|
||||
"$P_CLI request_size=16384 force_version=tls1 recsplit=0 \
|
||||
force_ciphersuite=TLS-RSA-WITH-AES-256-CBC-SHA" \
|
||||
0 \
|
||||
-s "Read from client: 16384 bytes read"
|
||||
|
||||
run_test "Large packet TLS 1.0 BlockCipher truncated MAC" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI request_size=16384 force_version=tls1 \
|
||||
"$P_CLI request_size=16384 force_version=tls1 recsplit=0 \
|
||||
force_ciphersuite=TLS-RSA-WITH-AES-256-CBC-SHA \
|
||||
trunc_hmac=1" \
|
||||
0 \
|
||||
|
@ -2206,7 +2263,8 @@ run_test "Large packet TLS 1.2 BlockCipher" \
|
|||
|
||||
run_test "Large packet TLS 1.2 BlockCipher larger MAC" \
|
||||
"$P_SRV" \
|
||||
"$P_CLI request_size=16384 force_version=tls1_2 force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384" \
|
||||
"$P_CLI request_size=16384 force_version=tls1_2 \
|
||||
force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384" \
|
||||
0 \
|
||||
-s "Read from client: 16384 bytes read"
|
||||
|
||||
|
|
Loading…
Reference in a new issue