Merge remote-tracking branch 'nw/misc' into mbedtls-1.3
* nw/misc:
Typos and doc additions
diff --git a/ChangeLog b/ChangeLog
index 75ddfdb..d44463f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,8 +3,15 @@
= mbed TLS 1.3 branch
Security
+ * With authmode set to SSL_VERIFY_OPTIONAL, verification of keyUsage and
+ extendedKeyUsage on the leaf certificate was lost (results not accessible
+ via ssl_get_verify_results()).
+ * Add countermeasure against "Lucky 13 strikes back" cache-based attack,
+ https://dl.acm.org/citation.cfm?id=2714625
Features
+ * Improve ECC performance by using more efficient doubling formulas
+ (contributed by Peter Dettman).
* Add x509_crt_verify_info() to display certificate verification results.
* Add support for reading DH parameters with privateValueLength included
(contributed by Daniel Kahn Gillmor).
@@ -28,6 +35,10 @@
errors on use of deprecated functions.
Bugfix
+ * Fix bug in ssl_mail_client when password is longer that username (found
+ by Bruno Pape).
+ * Fix undefined behaviour (memcmp( NULL, NULL, 0 );) in X.509 modules
+ (detected by Clang's 3.6 UBSan).
* mpi_size() and mpi_msb() would segfault when called on an mpi that is
initialized but not set (found by pravic).
* Fix detection of support for getrandom() on Linux (reported by syzzer) by
@@ -579,6 +590,67 @@
* RSA blinding on CRT operations to counter timing attacks
(found by Cyril Arnaud and Pierre-Alain Fouque)
+
+= Version 1.2.14 released 2015-05-??
+
+Security
+ * Fix potential invalid memory read in the server, that allows a client to
+ crash it remotely (found by Caj Larsson).
+ * Fix potential invalid memory read in certificate parsing, that allows a
+ client to crash the server remotely if client authentication is enabled
+ (found using Codenomicon Defensics).
+ * Add countermeasure against "Lucky 13 strikes back" cache-based attack,
+ https://dl.acm.org/citation.cfm?id=2714625
+
+Bugfix
+ * Fix bug in Via Padlock support (found by Nikos Mavrogiannopoulos).
+ * Fix hardclock() (only used in the benchmarking program) with some
+ versions of mingw64 (found by kxjhlele).
+ * Fix warnings from mingw64 in timing.c (found by kxjklele).
+ * Fix potential unintended sign extension in asn1_get_len() on 64-bit
+ platforms (found with Coverity Scan).
+
+= Version 1.2.13 released 2015-02-16
+Note: Although PolarSSL has been renamed to mbed TLS, no changes reflecting
+ this will be made in the 1.2 branch at this point.
+
+Security
+ * Fix remotely-triggerable uninitialised pointer dereference caused by
+ crafted X.509 certificate (TLS server is not affected if it doesn't ask
+ for a client certificate) (found using Codenomicon Defensics).
+ * Fix remotely-triggerable memory leak caused by crafted X.509 certificates
+ (TLS server is not affected if it doesn't ask for a client certificate)
+ (found using Codenomicon Defensics).
+ * Fix potential stack overflow while parsing crafted X.509 certificates
+ (TLS server is not affected if it doesn't ask for a client certificate)
+ found using Codenomicon Defensics).
+ * Fix buffer overread of size 1 when parsing crafted X.509 certificates
+ (TLS server is not affected if it doesn't ask for a client certificate).
+
+Bugfix
+ * Fix potential undefined behaviour in Camellia.
+ * Fix memory leaks in PKCS#5 and PKCS#12.
+ * Stack buffer overflow if ctr_drbg_update() is called with too large
+ add_len (found by Jean-Philippe Aumasson) (not triggerable remotely).
+ * Fix bug in MPI/bignum on s390/s390x (reported by Dan Horák) (introduced
+ in 1.2.12).
+ * Fix unchecked return code in x509_crt_parse_path() on Windows (found by
+ Peter Vaskovic).
+ * Fix assembly selection for MIPS64 (thanks to James Cowgill).
+ * ssl_get_verify_result() now works even if the handshake was aborted due
+ to a failed verification (found by Fredrik Axelsson).
+ * Skip writing and parsing signature_algorithm extension if none of the
+ key exchanges enabled needs certificates. This fixes a possible interop
+ issue with some servers when a zero-length extension was sent. (Reported
+ by Peter Dettman.)
+ * On a 0-length input, base64_encode() did not correctly set output length
+ (found by Hendrik van den Boogaard).
+
+Changes
+ * Blind RSA private operations even when POLARSSL_RSA_NO_CRT is defined.
+ * Forbid repeated extensions in X.509 certificates.
+ * Add compile-time option POLARSSL_X509_MAX_INTERMEDIATE_CA to limit the
+ length of an X.509 verification chain (default = 8).
= Version 1.2.12 released 2014-10-24
Security
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index a7b9a07..730594a 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1983,7 +1983,8 @@
*/
int ssl_check_cert_usage( const x509_crt *cert,
const ssl_ciphersuite_t *ciphersuite,
- int cert_endpoint );
+ int cert_endpoint,
+ int *flags );
#endif /* POLARSSL_X509_CRT_PARSE_C */
/* constant-time buffer comparison */
diff --git a/library/ecp.c b/library/ecp.c
index be6b0d5..adef09e 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -911,70 +911,86 @@
/*
* Point doubling R = 2 P, Jacobian coordinates
*
- * http://www.hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian/doubling/dbl-2007-bl.op3
- * with heavy variable renaming, some reordering and one minor modification
- * (a = 2 * b, c = d - 2a replaced with c = d, c = c - b, c = c - b)
- * in order to use a lot less intermediate variables (6 vs 25).
+ * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 .
*
- * Cost: 1D := 2M + 8S
+ * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR
+ * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring.
+ *
+ * Standard optimizations are applied when curve parameter A is one of { 0, -3 }.
+ *
+ * Cost: 1D := 3M + 4S (A == 0)
+ * 4M + 4S (A == -3)
+ * 3M + 6S + 1a otherwise
*/
static int ecp_double_jac( const ecp_group *grp, ecp_point *R,
const ecp_point *P )
{
int ret;
- mpi T1, T2, T3, X3, Y3, Z3;
+ mpi M, S, T, U;
#if defined(POLARSSL_SELF_TEST)
dbl_count++;
#endif
- mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 );
- mpi_init( &X3 ); mpi_init( &Y3 ); mpi_init( &Z3 );
-
- MPI_CHK( mpi_mul_mpi( &T3, &P->X, &P->X ) ); MOD_MUL( T3 );
- MPI_CHK( mpi_mul_mpi( &T2, &P->Y, &P->Y ) ); MOD_MUL( T2 );
- MPI_CHK( mpi_mul_mpi( &Y3, &T2, &T2 ) ); MOD_MUL( Y3 );
- MPI_CHK( mpi_add_mpi( &X3, &P->X, &T2 ) ); MOD_ADD( X3 );
- MPI_CHK( mpi_mul_mpi( &X3, &X3, &X3 ) ); MOD_MUL( X3 );
- MPI_CHK( mpi_sub_mpi( &X3, &X3, &Y3 ) ); MOD_SUB( X3 );
- MPI_CHK( mpi_sub_mpi( &X3, &X3, &T3 ) ); MOD_SUB( X3 );
- MPI_CHK( mpi_mul_int( &T1, &X3, 2 ) ); MOD_ADD( T1 );
- MPI_CHK( mpi_mul_mpi( &Z3, &P->Z, &P->Z ) ); MOD_MUL( Z3 );
- MPI_CHK( mpi_mul_mpi( &X3, &Z3, &Z3 ) ); MOD_MUL( X3 );
- MPI_CHK( mpi_mul_int( &T3, &T3, 3 ) ); MOD_ADD( T3 );
+ mpi_init( &M ); mpi_init( &S ); mpi_init( &T ); mpi_init( &U );
/* Special case for A = -3 */
if( grp->A.p == NULL )
{
- MPI_CHK( mpi_mul_int( &X3, &X3, 3 ) );
- X3.s = -1; /* mpi_mul_int doesn't handle negative numbers */
- MOD_SUB( X3 );
+ /* M = 3(X + Z^2)(X - Z^2) */
+ MPI_CHK( mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
+ MPI_CHK( mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T );
+ MPI_CHK( mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U );
+ MPI_CHK( mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S );
+ MPI_CHK( mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
}
else
{
- MPI_CHK( mpi_mul_mpi( &X3, &X3, &grp->A ) ); MOD_MUL( X3 );
+ /* M = 3.X^2 */
+ MPI_CHK( mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S );
+ MPI_CHK( mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
+
+ /* Optimize away for "koblitz" curves with A = 0 */
+ if( mpi_cmp_int( &grp->A, 0 ) != 0 )
+ {
+ /* M += A.Z^4 */
+ MPI_CHK( mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
+ MPI_CHK( mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T );
+ MPI_CHK( mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S );
+ MPI_CHK( mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M );
+ }
}
- MPI_CHK( mpi_add_mpi( &T3, &T3, &X3 ) ); MOD_ADD( T3 );
- MPI_CHK( mpi_mul_mpi( &X3, &T3, &T3 ) ); MOD_MUL( X3 );
- MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 );
- MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 );
- MPI_CHK( mpi_sub_mpi( &T1, &T1, &X3 ) ); MOD_SUB( T1 );
- MPI_CHK( mpi_mul_mpi( &T1, &T3, &T1 ) ); MOD_MUL( T1 );
- MPI_CHK( mpi_mul_int( &T3, &Y3, 8 ) ); MOD_ADD( T3 );
- MPI_CHK( mpi_sub_mpi( &Y3, &T1, &T3 ) ); MOD_SUB( Y3 );
- MPI_CHK( mpi_add_mpi( &T1, &P->Y, &P->Z ) ); MOD_ADD( T1 );
- MPI_CHK( mpi_mul_mpi( &T1, &T1, &T1 ) ); MOD_MUL( T1 );
- MPI_CHK( mpi_sub_mpi( &T1, &T1, &T2 ) ); MOD_SUB( T1 );
- MPI_CHK( mpi_sub_mpi( &Z3, &T1, &Z3 ) ); MOD_SUB( Z3 );
+ /* S = 4.X.Y^2 */
+ MPI_CHK( mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T );
+ MPI_CHK( mpi_shift_l( &T, 1 ) ); MOD_ADD( T );
+ MPI_CHK( mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S );
+ MPI_CHK( mpi_shift_l( &S, 1 ) ); MOD_ADD( S );
- MPI_CHK( mpi_copy( &R->X, &X3 ) );
- MPI_CHK( mpi_copy( &R->Y, &Y3 ) );
- MPI_CHK( mpi_copy( &R->Z, &Z3 ) );
+ /* U = 8.Y^4 */
+ MPI_CHK( mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U );
+ MPI_CHK( mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
+
+ /* T = M^2 - 2.S */
+ MPI_CHK( mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T );
+ MPI_CHK( mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
+ MPI_CHK( mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
+
+ /* S = M(S - T) - U */
+ MPI_CHK( mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S );
+ MPI_CHK( mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S );
+ MPI_CHK( mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S );
+
+ /* U = 2.Y.Z */
+ MPI_CHK( mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U );
+ MPI_CHK( mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
+
+ MPI_CHK( mpi_copy( &R->X, &T ) );
+ MPI_CHK( mpi_copy( &R->Y, &S ) );
+ MPI_CHK( mpi_copy( &R->Z, &U ) );
cleanup:
- mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 );
- mpi_free( &X3 ); mpi_free( &Y3 ); mpi_free( &Z3 );
+ mpi_free( &M ); mpi_free( &S ); mpi_free( &T ); mpi_free( &U );
return( ret );
}
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index dad6872..5f01a01 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -829,6 +829,7 @@
{
ssl_key_cert *cur, *list, *fallback = NULL;
pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
+ int flags;
#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
if( ssl->handshake->sni_key_cert != NULL )
@@ -862,7 +863,7 @@
* and decrypting with the same RSA key.
*/
if( ssl_check_cert_usage( cur->cert, ciphersuite_info,
- SSL_IS_SERVER ) != 0 )
+ SSL_IS_SERVER, &flags ) != 0 )
{
SSL_DEBUG_MSG( 3, ( "certificate mismatch: "
"(extended) key usage extension" ) );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index d2e0c52..f079adc 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1825,7 +1825,8 @@
ssl->in_msglen );
md_hmac_finish( &ssl->transform_in->md_ctx_dec,
ssl->in_msg + ssl->in_msglen );
- for( j = 0; j < extra_run; j++ )
+ /* Call md_process at least once due to cache attacks */
+ for( j = 0; j < extra_run + 1; j++ )
md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
md_hmac_reset( &ssl->transform_in->md_ctx_dec );
@@ -2859,7 +2860,8 @@
if( ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
ciphersuite_info,
- ! ssl->endpoint ) != 0 )
+ ! ssl->endpoint,
+ &ssl->session_negotiate->verify_result ) != 0 )
{
SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
if( ret == 0 )
@@ -5199,8 +5201,10 @@
#if defined(POLARSSL_X509_CRT_PARSE_C)
int ssl_check_cert_usage( const x509_crt *cert,
const ssl_ciphersuite_t *ciphersuite,
- int cert_endpoint )
+ int cert_endpoint,
+ int *flags )
{
+ int ret = 0;
#if defined(POLARSSL_X509_CHECK_KEY_USAGE)
int usage = 0;
#endif
@@ -5213,6 +5217,7 @@
!defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
((void) cert);
((void) cert_endpoint);
+ ((void) flags);
#endif
#if defined(POLARSSL_X509_CHECK_KEY_USAGE)
@@ -5252,7 +5257,10 @@
}
if( x509_crt_check_key_usage( cert, usage ) != 0 )
- return( -1 );
+ {
+ *flags |= BADCERT_KEY_USAGE;
+ ret = -1;
+ }
#else
((void) ciphersuite);
#endif /* POLARSSL_X509_CHECK_KEY_USAGE */
@@ -5270,10 +5278,13 @@
}
if( x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 )
- return( -1 );
+ {
+ *flags |= BADCERT_EXT_KEY_USAGE;
+ ret = -1;
+ }
#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */
- return( 0 );
+ return( ret );
}
#endif /* POLARSSL_X509_CRT_PARSE_C */
diff --git a/library/x509_crl.c b/library/x509_crl.c
index e2076a6..de2079f 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -462,7 +462,8 @@
if( crl->sig_oid1.len != crl->sig_oid2.len ||
memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 ||
sig_params1.len != sig_params2.len ||
- memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 )
+ ( sig_params1.len != 0 &&
+ memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
{
x509_crl_free( crl );
return( POLARSSL_ERR_X509_SIG_MISMATCH );
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 4e4d806..fe9e552 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -760,7 +760,8 @@
if( crt->sig_oid1.len != crt->sig_oid2.len ||
memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 ||
sig_params1.len != sig_params2.len ||
- memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 )
+ ( sig_params1.len != 0 &&
+ memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
{
x509_crt_free( crt );
return( POLARSSL_ERR_X509_SIG_MISMATCH );
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index fcda1dd..27c57a1 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -722,7 +722,7 @@
polarssl_printf( " > Write username to server: %s", opt.user_name );
fflush( stdout );
- n = sizeof( buf );
+ n = sizeof( base );
ret = base64_encode( base, &n, (const unsigned char *) opt.user_name,
strlen( opt.user_name ) );
@@ -743,6 +743,7 @@
polarssl_printf( " > Write password to server: %s", opt.user_pwd );
fflush( stdout );
+ n = sizeof( base );
ret = base64_encode( base, &n, (const unsigned char *) opt.user_pwd,
strlen( opt.user_pwd ) );
diff --git a/programs/test/o_p_test.c b/programs/test/o_p_test.c
index d949d51..f0ade14 100644
--- a/programs/test/o_p_test.c
+++ b/programs/test/o_p_test.c
@@ -52,8 +52,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
#endif
#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_RSA_C) || \
diff --git a/tests/compat.sh b/tests/compat.sh
index 554adef..5a3c222 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -679,7 +679,7 @@
P_SERVER_ARGS="server_port=$PORT server_addr=0.0.0.0 force_version=$MODE arc4=1"
O_SERVER_ARGS="-accept $PORT -www -cipher NULL,ALL -$MODE"
G_SERVER_ARGS="-p $PORT --http"
- G_SERVER_PRIO="EXPORT:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
+ G_SERVER_PRIO="NORMAL:+ARCFOUR-128:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
P_CLIENT_ARGS="server_port=$PORT force_version=$MODE"
O_CLIENT_ARGS="-connect localhost:$PORT -$MODE"
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 75c5942..5cf4ff6 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1878,6 +1878,17 @@
-c "Processing of the Certificate handshake message failed" \
-C "Ciphersuite is TLS-"
+run_test "keyUsage cli: KeyEncipherment, DHE-RSA: fail, soft" \
+ "$O_SRV -key data_files/server2.key \
+ -cert data_files/server2.ku-ke.crt" \
+ "$P_CLI debug_level=1 auth_mode=optional \
+ force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA" \
+ 0 \
+ -c "bad certificate (usage extensions)" \
+ -C "Processing of the Certificate handshake message failed" \
+ -c "Ciphersuite is TLS-" \
+ -c "! Usage does not match the keyUsage extension"
+
run_test "keyUsage cli: DigitalSignature, DHE-RSA: OK" \
"$O_SRV -key data_files/server2.key \
-cert data_files/server2.ku-ds.crt" \
@@ -1898,6 +1909,17 @@
-c "Processing of the Certificate handshake message failed" \
-C "Ciphersuite is TLS-"
+run_test "keyUsage cli: DigitalSignature, RSA: fail, soft" \
+ "$O_SRV -key data_files/server2.key \
+ -cert data_files/server2.ku-ds.crt" \
+ "$P_CLI debug_level=1 auth_mode=optional \
+ force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 0 \
+ -c "bad certificate (usage extensions)" \
+ -C "Processing of the Certificate handshake message failed" \
+ -c "Ciphersuite is TLS-" \
+ -c "! Usage does not match the keyUsage extension"
+
# Tests for keyUsage in leaf certificates, part 3:
# server-side checking of client cert