Merge pull request #3409 from bensze01/license-2.7
[Backport 2.7] Update license headers to reflect the Apache-2.0 OR GPL-2.0-or-later licensing
diff --git a/ChangeLog.d/montmul-cmp-branch.txt b/ChangeLog.d/montmul-cmp-branch.txt
new file mode 100644
index 0000000..5994518
--- /dev/null
+++ b/ChangeLog.d/montmul-cmp-branch.txt
@@ -0,0 +1,6 @@
+Security
+ * Fix a side channel vulnerability in modular exponentiation that could
+ reveal an RSA private key used in a secure enclave. Noticed by Sangho Lee,
+ Ming-Wei Shih, Prasun Gera, Taesoo Kim and Hyesoon Kim (Georgia Institute
+ of Technology); and Marcus Peinado (Microsoft Research). Reported by Raoul
+ Strackx (Fortanix) in #3394.
diff --git a/ChangeLog.d/uniformize_bounds_checks.txt b/ChangeLog.d/uniformize_bounds_checks.txt
new file mode 100644
index 0000000..210ab10
--- /dev/null
+++ b/ChangeLog.d/uniformize_bounds_checks.txt
@@ -0,0 +1,9 @@
+Bugfix
+ * Add additional bounds checks in ssl_write_client_hello() preventing
+ output buffer overflow if the configuration declared a buffer that was
+ too small.
+Changes
+ * Abort the ClientHello writing function as soon as some extension doesn't
+ fit into the record buffer. Previously, such extensions were silently
+ dropped. As a consequence, the TLS handshake now fails when the output
+ buffer is not large enough to hold the ClientHello.
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 62990b6..2c55bcc 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -121,6 +121,7 @@
* RSA 4 11
* ECP 4 9 (Started from top)
* MD 5 5
+ * SSL 5 1 (Started from 0x5E80)
* CIPHER 6 8
* SSL 6 17 (Started from top)
* SSL 7 31
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 2e797c8..3d133ab 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -137,6 +137,7 @@
#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 /**< Record header looks valid but is not expected. */
#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */
#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */
+#define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 /**< Invalid value in SSL config */
/*
* Various constants
@@ -151,6 +152,9 @@
#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */
#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */
+#define MBEDTLS_SSL_MAX_ALPN_NAME_LEN 255 /*!< Maximum size in bytes of a protocol name in alpn ext., RFC 7301 */
+
+#define MBEDTLS_SSL_MAX_ALPN_LIST_LEN 65535 /*!< Maximum size in bytes of list in alpn ext., RFC 7301 */
/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c
* NONE must be zero so that memset()ing structure to zero works */
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 74716e6..4aa7463 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -183,6 +183,12 @@
+ MBEDTLS_SSL_PADDING_ADD \
)
+/* Maximum size in bytes of list in sig-hash algorithm ext., RFC 5246 */
+#define MBEDTLS_SSL_MAX_SIG_HASH_ALG_LIST_LEN 65534
+
+/* Maximum size in bytes of list in supported elliptic curve ext., RFC 4492 */
+#define MBEDTLS_SSL_MAX_CURVE_LIST_LEN 65535
+
/*
* Check that we obey the standard's message size bounds
*/
@@ -211,6 +217,41 @@
#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0)
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1)
+/**
+ * \brief This function checks if the remaining size in a buffer is
+ * greater or equal than a needed space.
+ *
+ * \param cur Pointer to the current position in the buffer.
+ * \param end Pointer to one past the end of the buffer.
+ * \param need Needed space in bytes.
+ *
+ * \return Zero if the needed space is available in the buffer, non-zero
+ * otherwise.
+ */
+static inline int mbedtls_ssl_chk_buf_ptr( const uint8_t *cur,
+ const uint8_t *end, size_t need )
+{
+ return( ( cur > end ) || ( need > (size_t)( end - cur ) ) );
+}
+
+/**
+ * \brief This macro checks if the remaining size in a buffer is
+ * greater or equal than a needed space. If it is not the case,
+ * it returns an SSL_BUFFER_TOO_SMALL error.
+ *
+ * \param cur Pointer to the current position in the buffer.
+ * \param end Pointer to one past the end of the buffer.
+ * \param need Needed space in bytes.
+ *
+ */
+#define MBEDTLS_SSL_CHK_BUF_PTR( cur, end, need ) \
+ do { \
+ if( mbedtls_ssl_chk_buf_ptr( ( cur ), ( end ), ( need ) ) != 0 ) \
+ { \
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); \
+ } \
+ } while( 0 )
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/library/bignum.c b/library/bignum.c
index 9b80633..84a43c8 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -254,6 +254,22 @@
}
/*
+ * Conditionally assign dest = src, without leaking information
+ * about whether the assignment was made or not.
+ * dest and src must be arrays of limbs of size n.
+ * assign must be 0 or 1.
+ */
+static void mpi_safe_cond_assign( size_t n,
+ mbedtls_mpi_uint *dest,
+ const mbedtls_mpi_uint *src,
+ unsigned char assign )
+{
+ size_t i;
+ for( i = 0; i < n; i++ )
+ dest[i] = dest[i] * ( 1 - assign ) + src[i] * assign;
+}
+
+/*
* Conditionally assign X = Y, without leaking information
* about whether the assignment was made or not.
* (Leaking information about the respective sizes of X and Y is ok however.)
@@ -270,10 +286,9 @@
X->s = X->s * ( 1 - assign ) + Y->s * assign;
- for( i = 0; i < Y->n; i++ )
- X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
+ mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
- for( ; i < X->n; i++ )
+ for( i = Y->n; i < X->n; i++ )
X->p[i] *= ( 1 - assign );
cleanup:
@@ -1116,10 +1131,24 @@
return( ret );
}
-/*
- * Helper for mbedtls_mpi subtraction
+/**
+ * Helper for mbedtls_mpi subtraction.
+ *
+ * Calculate d - s where d and s have the same size.
+ * This function operates modulo (2^ciL)^n and returns the carry
+ * (1 if there was a wraparound, i.e. if `d < s`, and 0 otherwise).
+ *
+ * \param n Number of limbs of \p d and \p s.
+ * \param[in,out] d On input, the left operand.
+ * On output, the result of the subtraction:
+ * \param[in] s The right operand.
+ *
+ * \return 1 if `d < s`.
+ * 0 if `d >= s`.
*/
-static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
+static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
+ mbedtls_mpi_uint *d,
+ const mbedtls_mpi_uint *s )
{
size_t i;
mbedtls_mpi_uint c, z;
@@ -1130,24 +1159,18 @@
c = ( *d < *s ) + z; *d -= *s;
}
- while( c != 0 )
- {
- z = ( *d < c ); *d -= c;
- c = z; i++; d++;
- }
+ return( c );
}
/*
- * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
+ * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)
*/
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
mbedtls_mpi TB;
int ret;
size_t n;
-
- if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
- return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
+ mbedtls_mpi_uint carry;
mbedtls_mpi_init( &TB );
@@ -1171,7 +1194,18 @@
if( B->p[n - 1] != 0 )
break;
- mpi_sub_hlp( n, B->p, X->p );
+ carry = mpi_sub_hlp( n, X->p, B->p );
+ if( carry != 0 )
+ {
+ /* Propagate the carry to the first nonzero limb of X. */
+ for( ; n < X->n && X->p[n] == 0; n++ )
+ --X->p[n];
+ /* If we ran out of space for the carry, it means that the result
+ * is negative. */
+ if( n == X->n )
+ return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
+ --X->p[n];
+ }
cleanup:
@@ -1723,18 +1757,34 @@
*mm = ~x + 1;
}
-/*
- * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
+/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
+ *
+ * \param[in,out] A One of the numbers to multiply.
+ * It must have at least as many limbs as N
+ * (A->n >= N->n), and any limbs beyond n are ignored.
+ * On successful completion, A contains the result of
+ * the multiplication A * B * R^-1 mod N where
+ * R = (2^ciL)^n.
+ * \param[in] B One of the numbers to multiply.
+ * It must be nonzero and must not have more limbs than N
+ * (B->n <= N->n).
+ * \param[in] N The modulo. N must be odd.
+ * \param mm The value calculated by `mpi_montg_init(&mm, N)`.
+ * This is -N^-1 mod 2^ciL.
+ * \param[in,out] T A bignum for temporary storage.
+ * It must be at least twice the limb size of N plus 2
+ * (T->n >= 2 * (N->n + 1)).
+ * Its initial content is unused and
+ * its final content is indeterminate.
+ * Note that unlike the usual convention in the library
+ * for `const mbedtls_mpi*`, the content of T can change.
*/
-static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
+static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
const mbedtls_mpi *T )
{
size_t i, n, m;
mbedtls_mpi_uint u0, u1, *d;
- if( T->n < N->n + 1 || T->p == NULL )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
-
memset( T->p, 0, T->n * ciL );
d = T->p;
@@ -1755,21 +1805,33 @@
*d++ = u0; d[n + 1] = 0;
}
- memcpy( A->p, d, ( n + 1 ) * ciL );
+ /* At this point, d is either the desired result or the desired result
+ * plus N. We now potentially subtract N, avoiding leaking whether the
+ * subtraction is performed through side channels. */
- if( mbedtls_mpi_cmp_abs( A, N ) >= 0 )
- mpi_sub_hlp( n, N->p, A->p );
- else
- /* prevent timing attacks */
- mpi_sub_hlp( n, A->p, T->p );
-
- return( 0 );
+ /* Copy the n least significant limbs of d to A, so that
+ * A = d if d < N (recall that N has n limbs). */
+ memcpy( A->p, d, n * ciL );
+ /* If d >= N then we want to set A to d - N. To prevent timing attacks,
+ * do the calculation without using conditional tests. */
+ /* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */
+ d[n] += 1;
+ d[n] -= mpi_sub_hlp( n, d, N->p );
+ /* If d0 < N then d < (2^biL)^n
+ * so d[n] == 0 and we want to keep A as it is.
+ * If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n
+ * so d[n] == 1 and we want to set A to the result of the subtraction
+ * which is d - (2^biL)^n, i.e. the n least significant limbs of d.
+ * This exactly corresponds to a conditional assignment. */
+ mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] );
}
/*
* Montgomery reduction: A = A * R^-1 mod N
+ *
+ * See mpi_montmul() regarding constraints and guarantees on the parameters.
*/
-static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
+static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
{
mbedtls_mpi_uint z = 1;
mbedtls_mpi U;
@@ -1777,7 +1839,7 @@
U.n = U.s = (int) z;
U.p = &z;
- return( mpi_montmul( A, &U, N, mm, T ) );
+ mpi_montmul( A, &U, N, mm, T );
}
/*
@@ -1856,13 +1918,13 @@
else
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
- MBEDTLS_MPI_CHK( mpi_montmul( &W[1], &RR, N, mm, &T ) );
+ mpi_montmul( &W[1], &RR, N, mm, &T );
/*
* X = R^2 * R^-1 mod N = R mod N
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
- MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
+ mpi_montred( X, N, mm, &T );
if( wsize > 1 )
{
@@ -1875,7 +1937,7 @@
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
for( i = 0; i < wsize - 1; i++ )
- MBEDTLS_MPI_CHK( mpi_montmul( &W[j], &W[j], N, mm, &T ) );
+ mpi_montmul( &W[j], &W[j], N, mm, &T );
/*
* W[i] = W[i - 1] * W[1]
@@ -1885,7 +1947,7 @@
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
- MBEDTLS_MPI_CHK( mpi_montmul( &W[i], &W[1], N, mm, &T ) );
+ mpi_montmul( &W[i], &W[1], N, mm, &T );
}
}
@@ -1922,7 +1984,7 @@
/*
* out of window, square X
*/
- MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
+ mpi_montmul( X, X, N, mm, &T );
continue;
}
@@ -1940,12 +2002,12 @@
* X = X^wsize R^-1 mod N
*/
for( i = 0; i < wsize; i++ )
- MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
+ mpi_montmul( X, X, N, mm, &T );
/*
* X = X * W[wbits] R^-1 mod N
*/
- MBEDTLS_MPI_CHK( mpi_montmul( X, &W[wbits], N, mm, &T ) );
+ mpi_montmul( X, &W[wbits], N, mm, &T );
state--;
nbits = 0;
@@ -1958,18 +2020,18 @@
*/
for( i = 0; i < nbits; i++ )
{
- MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
+ mpi_montmul( X, X, N, mm, &T );
wbits <<= 1;
if( ( wbits & ( one << wsize ) ) != 0 )
- MBEDTLS_MPI_CHK( mpi_montmul( X, &W[1], N, mm, &T ) );
+ mpi_montmul( X, &W[1], N, mm, &T );
}
/*
* X = A^E * R * R^-1 mod N = A^E mod N
*/
- MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
+ mpi_montred( X, N, mm, &T );
if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
{
diff --git a/library/error.c b/library/error.c
index ede3b25..fa0e01f 100644
--- a/library/error.c
+++ b/library/error.c
@@ -522,6 +522,8 @@
mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" );
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) )
mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
+ if( use_ret == -(MBEDTLS_ERR_SSL_BAD_CONFIG) )
+ mbedtls_snprintf( buf, buflen, "SSL - Invalid value in SSL config" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index aeb7755..8276826 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -82,29 +82,26 @@
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
+static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t hostname_len;
*olen = 0;
if( ssl->hostname == NULL )
- return;
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
- ssl->hostname ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding server name extension: %s",
+ ssl->hostname ) );
hostname_len = strlen( ssl->hostname );
- if( end < p || (size_t)( end - p ) < hostname_len + 9 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, hostname_len + 9 );
/*
* Sect. 3, RFC 6066 (TLS Extensions Definitions)
@@ -148,16 +145,18 @@
memcpy( p, ssl->hostname, hostname_len );
*olen = hostname_len + 9;
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
-static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
+static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
@@ -165,21 +164,20 @@
* initial ClientHello, in which case also adding the renegotiation
* info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */
if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- return;
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding renegotiation extension" ) );
- if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 + ssl->verify_data_len );
/*
* Secure renegotiation
*/
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 )
+ & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO )
+ & 0xFF );
*p++ = 0x00;
*p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
@@ -188,6 +186,8 @@
memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
*olen = 5 + ssl->verify_data_len;
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_RENEGOTIATION */
@@ -196,14 +196,15 @@
*/
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
-static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
+static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t sig_alg_len = 0;
const int *md;
+
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
unsigned char *sig_alg_list = buf + 6;
#endif
@@ -211,9 +212,13 @@
*olen = 0;
if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
- return;
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding signature_algorithms extension" ) );
+
+ if( ssl->conf->sig_hashes == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
{
@@ -223,13 +228,19 @@
#if defined(MBEDTLS_RSA_C)
sig_alg_len += 2;
#endif
+ if( sig_alg_len > MBEDTLS_SSL_MAX_SIG_HASH_ALG_LIST_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "length in bytes of sig-hash-alg extension too big" ) );
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+ }
}
- if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ /* Empty signature algorithms list, this is a configuration error. */
+ if( sig_alg_len == 0 )
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, sig_alg_len + 6 );
/*
* Prepare signature_algorithms extension (TLS 1.2)
@@ -275,75 +286,75 @@
*p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
*olen = 6 + sig_alg_len;
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
+static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
unsigned char *elliptic_curve_list = p + 6;
size_t elliptic_curve_len = 0;
const mbedtls_ecp_curve_info *info;
-#if defined(MBEDTLS_ECP_C)
const mbedtls_ecp_group_id *grp_id;
-#else
- ((void) ssl);
-#endif
*olen = 0;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding supported_elliptic_curves extension" ) );
-#if defined(MBEDTLS_ECP_C)
- for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
-#else
- for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
-#endif
+ if( ssl->conf->curve_list == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+ for( grp_id = ssl->conf->curve_list;
+ *grp_id != MBEDTLS_ECP_DP_NONE;
+ grp_id++ )
{
-#if defined(MBEDTLS_ECP_C)
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
-#endif
if( info == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) );
- return;
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "invalid curve in ssl configuration" ) );
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
}
-
elliptic_curve_len += 2;
+
+ if( elliptic_curve_len > MBEDTLS_SSL_MAX_CURVE_LIST_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "malformed supported_elliptic_curves extension in config" ) );
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+ }
}
- if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ /* Empty elliptic curve list, this is a configuration error. */
+ if( elliptic_curve_len == 0 )
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + elliptic_curve_len );
elliptic_curve_len = 0;
-#if defined(MBEDTLS_ECP_C)
- for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
-#else
- for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
-#endif
+ for( grp_id = ssl->conf->curve_list;
+ *grp_id != MBEDTLS_ECP_DP_NONE;
+ grp_id++ )
{
-#if defined(MBEDTLS_ECP_C)
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
-#endif
elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
}
- if( elliptic_curve_len == 0 )
- return;
-
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 )
+ & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES )
+ & 0xFF );
*p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
@@ -352,27 +363,28 @@
*p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
*olen = 6 + elliptic_curve_len;
+
+ return( 0 );
}
-static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
+static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
+ (void) ssl; /* ssl used for debugging only */
*olen = 0;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding supported_point_formats extension" ) );
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
- if( end < p || (size_t)( end - p ) < 6 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
-
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 )
+ & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS )
+ & 0xFF );
*p++ = 0x00;
*p++ = 2;
@@ -381,33 +393,32 @@
*p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
*olen = 6;
+
+ return( 0 );
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
+static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
int ret;
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t kkpp_len;
*olen = 0;
/* Skip costly extension if we can't use EC J-PAKE anyway */
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
- return;
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding ecjpake_kkpp extension" ) );
- if( end - p < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
@@ -423,19 +434,20 @@
MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
- p + 2, end - p - 2, &kkpp_len,
- ssl->conf->f_rng, ssl->conf->p_rng );
+ p + 2, end - p - 2, &kkpp_len,
+ ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
- MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
- return;
+ MBEDTLS_SSL_DEBUG_RET( 1 ,
+ "mbedtls_ecjpake_write_round_one", ret );
+ return( ret );
}
ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
if( ssl->handshake->ecjpake_cache == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
- return;
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
}
memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
@@ -446,12 +458,7 @@
MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
kkpp_len = ssl->handshake->ecjpake_cache_len;
-
- if( (size_t)( end - p - 2 ) < kkpp_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p + 2, end, kkpp_len );
memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
}
@@ -460,33 +467,33 @@
*p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
*olen = kkpp_len + 4;
+
+ return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
+static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
- if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
- return;
- }
+ if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE )
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding max_fragment_length extension" ) );
- if( end < p || (size_t)( end - p ) < 5 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 )
+ & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH )
+ & 0xFF );
*p++ = 0x00;
*p++ = 1;
@@ -494,30 +501,28 @@
*p++ = ssl->conf->mfl_code;
*olen = 5;
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
+static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
- {
- return;
- }
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding truncated_hmac extension" ) );
- if( end < p || (size_t)( end - p ) < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
@@ -526,32 +531,29 @@
*p++ = 0x00;
*olen = 4;
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
+static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- return;
- }
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
- "extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding encrypt_then_mac extension" ) );
- if( end < p || (size_t)( end - p ) < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
@@ -560,65 +562,63 @@
*p++ = 0x00;
*olen = 4;
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
+static int ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- return;
- }
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
- "extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding extended_master_secret extension" ) );
- if( end < p || (size_t)( end - p ) < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 )
+ & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET )
+ & 0xFF );
*p++ = 0x00;
*p++ = 0x00;
*olen = 4;
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
+static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t tlen = ssl->session_negotiate->ticket_len;
*olen = 0;
if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
- {
- return;
- }
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding session ticket extension" ) );
- if( end < p || (size_t)( end - p ) < 4 + tlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ /* The addition is safe here since the ticket length is 16 bit. */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 + tlen );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
@@ -629,44 +629,40 @@
*olen = 4;
if( ssl->session_negotiate->ticket == NULL || tlen == 0 )
- {
- return;
- }
+ return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "sending session ticket of length %d", tlen ) );
memcpy( p, ssl->session_negotiate->ticket, tlen );
*olen += tlen;
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_ALPN)
-static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
+static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
{
unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t alpnlen = 0;
const char **cur;
*olen = 0;
if( ssl->conf->alpn_list == NULL )
- {
- return;
- }
+ return( 0 );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
- alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1;
+ alpnlen += strlen( *cur ) + 1;
- if( end < p || (size_t)( end - p ) < 6 + alpnlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + alpnlen );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
@@ -684,7 +680,11 @@
for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
{
- *p = (unsigned char)( strlen( *cur ) & 0xFF );
+ /*
+ * mbedtls_ssl_conf_set_alpn_protocols() checked that the length of
+ * protocol names is less than 255.
+ */
+ *p = (unsigned char)strlen( *cur );
memcpy( p + 1, *cur, *p );
p += 1 + *p;
}
@@ -698,6 +698,8 @@
/* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
+
+ return( 0 );
}
#endif /* MBEDTLS_SSL_ALPN */
@@ -754,9 +756,10 @@
*
* \return 0 if valid, else 1
*/
-static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_info,
- const mbedtls_ssl_context * ssl,
- int min_minor_ver, int max_minor_ver )
+static int ssl_validate_ciphersuite(
+ const mbedtls_ssl_ciphersuite_t * suite_info,
+ const mbedtls_ssl_context * ssl,
+ int min_minor_ver, int max_minor_ver )
{
(void) ssl;
if( suite_info == NULL )
@@ -791,8 +794,11 @@
{
int ret;
size_t i, n, olen, ext_len = 0;
+
unsigned char *buf;
unsigned char *p, *q;
+ const unsigned char *end;
+
unsigned char offer_compress;
const int *ciphersuites;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
@@ -819,23 +825,41 @@
if( ssl->conf->max_major_ver == 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, "
- "consider using mbedtls_ssl_config_defaults()" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "configured max major version is invalid, consider using mbedtls_ssl_config_defaults()" ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
+ buf = ssl->out_msg;
+ end = buf + MBEDTLS_SSL_MAX_CONTENT_LEN;
+
/*
- * 0 . 0 handshake type
- * 1 . 3 handshake length
+ * Check if there's enough space for the first part of the ClientHello
+ * consisting of the 38 bytes described below, the session identifier (at
+ * most 32 bytes) and its length (1 byte).
+ *
+ * Use static upper bounds instead of the actual values
+ * to allow the compiler to optimize this away.
+ */
+ MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 38 + 1 + 32 );
+
+ /*
+ * The 38 first bytes of the ClientHello:
+ * 0 . 0 handshake type (written later)
+ * 1 . 3 handshake length (written later)
* 4 . 5 highest version supported
* 6 . 9 current UNIX time
* 10 . 37 random bytes
+ *
+ * The current UNIX time (4 bytes) and following 28 random bytes are written
+ * by ssl_generate_random() into ssl->handshake->randbytes buffer and then
+ * copied from there into the output buffer.
*/
- buf = ssl->out_msg;
- p = buf + 4;
- mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
- ssl->conf->transport, p );
+ p = buf + 4;
+ mbedtls_ssl_write_version( ssl->conf->max_major_ver,
+ ssl->conf->max_minor_ver,
+ ssl->conf->transport, p );
p += 2;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
@@ -855,7 +879,7 @@
* 38 . 38 session id length
* 39 . 39+n session id
* 39+n . 39+n DTLS only: cookie length (1 byte)
- * 40+n . .. DTSL only: cookie
+ * 40+n . .. DTLS only: cookie
* .. . .. ciphersuitelist length (2 bytes)
* .. . .. ciphersuitelist
* .. . .. compression methods length (1 byte)
@@ -886,7 +910,8 @@
if( ssl->session_negotiate->ticket != NULL &&
ssl->session_negotiate->ticket_len != 0 )
{
- ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
+ ret = ssl->conf->f_rng( ssl->conf->p_rng,
+ ssl->session_negotiate->id, 32 );
if( ret != 0 )
return( ret );
@@ -896,6 +921,12 @@
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+ /*
+ * The first check of the output buffer size above (
+ * MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 38 + 1 + 32 );)
+ * has checked that there is enough space in the output buffer for the
+ * session identifier length byte and the session identifier (n <= 32).
+ */
*p++ = (unsigned char) n;
for( i = 0; i < n; i++ )
@@ -905,11 +936,26 @@
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
/*
+ * With 'n' being the length of the session identifier
+ *
+ * 39+n . 39+n DTLS only: cookie length (1 byte)
+ * 40+n . .. DTLS only: cookie
+ * .. . .. ciphersuitelist length (2 bytes)
+ * .. . .. ciphersuitelist
+ * .. . .. compression methods length (1 byte)
+ * .. . .. compression methods
+ * .. . .. extensions length (2 bytes)
+ * .. . .. extensions
+ */
+
+ /*
* DTLS cookie
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 1 );
+
if( ssl->handshake->verify_cookie == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) );
@@ -922,6 +968,9 @@
ssl->handshake->verify_cookie_len );
*p++ = ssl->handshake->verify_cookie_len;
+
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end,
+ ssl->handshake->verify_cookie_len );
memcpy( p, ssl->handshake->verify_cookie,
ssl->handshake->verify_cookie_len );
p += ssl->handshake->verify_cookie_len;
@@ -937,6 +986,8 @@
/* Skip writing ciphersuite length for now */
n = 0;
q = p;
+
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
p += 2;
for( i = 0; ciphersuites[i] != 0; i++ )
@@ -956,12 +1007,15 @@
uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info );
#endif
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+
n++;
*p++ = (unsigned char)( ciphersuites[i] >> 8 );
*p++ = (unsigned char)( ciphersuites[i] );
}
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) );
/*
* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
@@ -971,6 +1025,7 @@
#endif
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) );
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
*p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
*p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
n++;
@@ -981,6 +1036,8 @@
if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
+
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
*p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
*p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
n++;
@@ -1011,8 +1068,10 @@
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
- MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) );
+ MBEDTLS_SSL_COMPRESS_DEFLATE,
+ MBEDTLS_SSL_COMPRESS_NULL ) );
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 3 );
*p++ = 2;
*p++ = MBEDTLS_SSL_COMPRESS_DEFLATE;
*p++ = MBEDTLS_SSL_COMPRESS_NULL;
@@ -1023,27 +1082,45 @@
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d",
MBEDTLS_SSL_COMPRESS_NULL ) );
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
*p++ = 1;
*p++ = MBEDTLS_SSL_COMPRESS_NULL;
}
- // First write extensions, then the total length
- //
+ /* First write extensions, then the total length */
+
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_hostname_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_hostname_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
/* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added
* even if MBEDTLS_SSL_RENEGOTIATION is not defined. */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_renegotiation_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_renegotiation_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_signature_algorithms_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
@@ -1051,46 +1128,91 @@
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( uses_ec )
{
- ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_supported_elliptic_curves_ext", ret );
+ return( ret );
+ }
ext_len += olen;
- ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_supported_point_formats_ext", ret );
+ return( ret );
+ }
ext_len += olen;
}
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_ecjpake_kkpp_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_max_fragment_length_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_truncated_hmac_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_encrypt_then_mac_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_extended_ms_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_extended_ms_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_ALPN)
- ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_alpn_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_alpn_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
+ if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_session_ticket_ext", ret );
+ return( ret );
+ }
ext_len += olen;
#endif
@@ -1098,10 +1220,12 @@
((void) olen);
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
- ext_len ) );
+ ext_len ) );
if( ext_len > 0 )
{
+ /* No need to check for space here, because the extension
+ * writing functions already took care of that. */
*p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( ext_len ) & 0xFF );
p += ext_len;
@@ -1145,8 +1269,10 @@
ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
}
@@ -1155,9 +1281,12 @@
{
if( len != 1 || buf[0] != 0x00 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "non-zero length renegotiation info" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1180,9 +1309,12 @@
len != 1 ||
buf[0] != ssl->conf->mfl_code )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "non-matching max fragment length extension" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1198,9 +1330,12 @@
if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
len != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "non-matching truncated HMAC extension" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1221,9 +1356,12 @@
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
len != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "non-matching encrypt-then-MAC extension" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1244,9 +1382,12 @@
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
len != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "non-matching extended master secret extension" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1266,9 +1407,12 @@
if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
len != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "non-matching session ticket extension" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1349,8 +1493,10 @@
buf, len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( ret );
}
@@ -1369,8 +1515,10 @@
if( ssl->conf->alpn_list == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1550,12 +1698,13 @@
if( ssl->conf->renego_max_records >= 0 &&
ssl->renego_records_seen > ssl->conf->renego_max_records )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
- "but not honored by server" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "renegotiation requested, but not honored by server" ) );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "non-handshake message during renegotiation" ) );
ssl->keep_current_message = 1;
return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
@@ -1563,8 +1712,10 @@
#endif /* MBEDTLS_SSL_RENEGOTIATION */
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
@@ -1618,11 +1769,13 @@
ssl->major_ver > ssl->conf->max_major_ver ||
ssl->minor_ver > ssl->conf->max_minor_ver )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
- " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
- ssl->conf->min_major_ver, ssl->conf->min_minor_ver,
- ssl->major_ver, ssl->minor_ver,
- ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "server version out of bounds - min: [%d:%d], server: [%d:%d], max: [%d:%d]",
+ ssl->conf->min_major_ver,
+ ssl->conf->min_minor_ver,
+ ssl->major_ver, ssl->minor_ver,
+ ssl->conf->max_major_ver,
+ ssl->conf->max_minor_ver ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
@@ -1659,8 +1812,10 @@
ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
}
@@ -1699,26 +1854,32 @@
if( comp != MBEDTLS_SSL_COMPRESS_NULL )
#endif/* MBEDTLS_ZLIB_SUPPORT */
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "server hello, bad compression: %d", comp ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
/*
* Initialize update checksum functions
*/
- ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
+ ssl->transform_negotiate->ciphersuite_info =
+ mbedtls_ssl_ciphersuite_from_id( i );
if( ssl->transform_negotiate->ciphersuite_info == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "ciphersuite info for %04x not found", i ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
+ mbedtls_ssl_optimize_checksum( ssl,
+ ssl->transform_negotiate->ciphersuite_info );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
@@ -1752,8 +1913,10 @@
if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( ret );
}
}
@@ -1762,7 +1925,8 @@
ssl->handshake->resume ? "a" : "no" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d",
+ buf[37 + n] ) );
/*
* Perform cipher suite validation in same way as in ssl_write_client_hello.
@@ -1773,8 +1937,10 @@
if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1785,16 +1951,21 @@
}
}
- suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
- if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, ssl->minor_ver ) != 0 )
+ suite_info = mbedtls_ssl_ciphersuite_from_id(
+ ssl->session_negotiate->ciphersuite );
+ if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver,
+ ssl->minor_ver ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
if( comp != MBEDTLS_SSL_COMPRESS_NULL
#if defined(MBEDTLS_ZLIB_SUPPORT)
@@ -1803,15 +1974,18 @@
)
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
ssl->session_negotiate->compression = comp;
ext = buf + 40 + n;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
+ MBEDTLS_SSL_DEBUG_MSG( 2,
+ ( "server hello, total extension length: %d", ext_len ) );
while( ext_len )
{
@@ -1823,8 +1997,9 @@
if( ext_size + 4 > ext_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message(
+ ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -1844,7 +2019,8 @@
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "found max_fragment_length extension" ) );
if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
ext + 4, ext_size ) ) != 0 )
@@ -1883,7 +2059,8 @@
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "found extended_master_secret extension" ) );
if( ( ret = ssl_parse_extended_ms_ext( ssl,
ext + 4, ext_size ) ) != 0 )
@@ -1910,7 +2087,8 @@
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "found supported_point_formats extension" ) );
if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
ext + 4, ext_size ) ) != 0 )
@@ -1946,8 +2124,8 @@
#endif /* MBEDTLS_SSL_ALPN */
default:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
- ext_id ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "unknown extension found: %d (ignoring)", ext_id ) );
}
ext_len -= 4 + ext_size;
@@ -1964,9 +2142,11 @@
* Renegotiation security checks
*/
if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
+ ssl->conf->allow_legacy_renegotiation ==
+ MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "legacy renegotiation, breaking off handshake" ) );
handshake_failure = 1;
}
#if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -1974,12 +2154,14 @@
ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
renegotiation_info_seen == 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "renegotiation_info extension missing (secure)" ) );
handshake_failure = 1;
}
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
+ ssl->conf->allow_legacy_renegotiation ==
+ MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
handshake_failure = 1;
@@ -1988,15 +2170,18 @@
ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
renegotiation_info_seen == 1 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "renegotiation_info extension present (legacy)" ) );
handshake_failure = 1;
}
#endif /* MBEDTLS_SSL_RENEGOTIATION */
if( handshake_failure == 1 )
{
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
@@ -2007,7 +2192,8 @@
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
-static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
+static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl,
+ unsigned char **p,
unsigned char *end )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -2021,7 +2207,8 @@
* opaque dh_Ys<1..2^16-1>;
* } ServerDHParams;
*/
- if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
+ if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx,
+ p, end ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
return( ret );
@@ -2106,7 +2293,8 @@
if( ssl_check_server_ecdh_params( ssl ) != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "bad server key exchange message (ECDHE curve)" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@@ -2132,8 +2320,8 @@
*/
if( end - (*p) < 2 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
- "(psk_identity_hint length)" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "bad server key exchange message (psk_identity_hint length)" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
len = (*p)[0] << 8 | (*p)[1];
@@ -2141,8 +2329,8 @@
if( end - (*p) < (int) len )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
- "(psk_identity_hint length)" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "bad server key exchange message (psk_identity_hint length)" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@@ -2184,8 +2372,9 @@
* opaque random[46];
* } PreMasterSecret;
*/
- mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
- ssl->conf->transport, p );
+ mbedtls_ssl_write_version( ssl->conf->max_major_ver,
+ ssl->conf->max_minor_ver,
+ ssl->conf->transport, p );
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
{
@@ -2262,20 +2451,22 @@
/*
* Get hash algorithm
*/
- if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
+ if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) )
+ == MBEDTLS_MD_NONE )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported "
- "HashAlgorithm %d", *(p)[0] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "Server used unsupported HashAlgorithm %d", *(p)[0] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
/*
* Get signature algorithm
*/
- if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
+ if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) )
+ == MBEDTLS_PK_NONE )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported "
- "SignatureAlgorithm %d", (*p)[1] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@@ -2284,13 +2475,15 @@
*/
if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm %d that was not offered",
- *(p)[0] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "server used HashAlgorithm %d that was not offered", *(p)[0] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d",
+ (*p)[1] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d",
+ (*p)[0] ) );
*p += 2;
return( 0 );
@@ -2368,8 +2561,10 @@
if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( ret );
}
@@ -2391,8 +2586,10 @@
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
@@ -2411,10 +2608,12 @@
goto exit;
}
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must "
- "not be skipped" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "server key exchange message must not be skipped" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
@@ -2432,8 +2631,10 @@
if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
} /* FALLTROUGH */
@@ -2455,8 +2656,10 @@
if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
@@ -2473,8 +2676,10 @@
if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
@@ -2490,8 +2695,10 @@
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
@@ -2521,17 +2728,24 @@
if( ssl_parse_signature_algorithm( ssl, &p, end,
&md_alg, &pk_alg ) != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "bad server key exchange message" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
- if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
+ if( pk_alg !=
+ mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "bad server key exchange message" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
@@ -2560,8 +2774,10 @@
if( p > end - 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
sig_len = ( p[0] << 8 ) | p[1];
@@ -2570,8 +2786,10 @@
if( p != end - sig_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@@ -2618,27 +2836,34 @@
if( ssl->session_negotiate->peer_cert == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
/*
* Verify signature
*/
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
+ if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
+ pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
md_alg, hash, hashlen, p, sig_len ) ) != 0 )
{
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
return( ret );
}
@@ -2699,8 +2924,10 @@
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
@@ -2776,8 +3003,9 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
- size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
- | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
+ size_t sig_alg_len =
+ ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
+ | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
#if defined(MBEDTLS_DEBUG_C)
unsigned char* sig_alg;
size_t i;
@@ -2795,11 +3023,14 @@
* buf[...hdr_len + 3 + n + sig_alg_len],
* which is one less than we need the buf to be.
*/
- if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len )
+ if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl )
+ + 3 + n + sig_alg_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
}
@@ -2807,8 +3038,9 @@
sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
for( i = 0; i < sig_alg_len; i += 2 )
{
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d"
- ",%d", sig_alg[i], sig_alg[i + 1] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "Supported Signature Algorithm found: %d,%d",
+ sig_alg[i], sig_alg[i + 1] ) );
}
#endif
@@ -2897,9 +3129,9 @@
i = 6;
ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
- (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- &ssl->out_msg[i], n,
- ssl->conf->f_rng, ssl->conf->p_rng );
+ (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
+ &ssl->out_msg[i], n,
+ ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
@@ -2910,10 +3142,10 @@
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
- ssl->handshake->premaster,
- MBEDTLS_PREMASTER_SIZE,
- &ssl->handshake->pmslen,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+ ssl->handshake->premaster,
+ MBEDTLS_PREMASTER_SIZE,
+ &ssl->handshake->pmslen,
+ ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
return( ret );
@@ -2950,10 +3182,10 @@
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
- &ssl->handshake->pmslen,
- ssl->handshake->premaster,
- MBEDTLS_MPI_MAX_SIZE,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+ &ssl->handshake->pmslen,
+ ssl->handshake->premaster,
+ MBEDTLS_MPI_MAX_SIZE,
+ ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
return( ret );
@@ -2983,15 +3215,17 @@
if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or "
- "SSL buffer too short" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "psk identity too long or SSL buffer too short" ) );
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
}
ssl->out_msg[i++] = (unsigned char)( n >> 8 );
ssl->out_msg[i++] = (unsigned char)( n );
- memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
+ memcpy( ssl->out_msg + i,
+ ssl->conf->psk_identity,
+ ssl->conf->psk_identity_len );
i += ssl->conf->psk_identity_len;
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
@@ -3019,8 +3253,8 @@
if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long"
- " or SSL buffer too short" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "psk identity or DHM size too long or SSL buffer too short" ) );
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
}
@@ -3066,7 +3300,8 @@
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
ciphersuite_info->key_exchange ) ) != 0 )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
+ MBEDTLS_SSL_DEBUG_RET( 1,
+ "mbedtls_ssl_psk_derive_premaster", ret );
return( ret );
}
}
@@ -3259,8 +3494,9 @@
* Until we encounter a server that does not, we will take this
* shortcut.
*
- * Reason: Otherwise we should have running hashes for SHA512 and SHA224
- * in order to satisfy 'weird' needs from the server side.
+ * Reason: Otherwise we should have running hashes for SHA512 and
+ * SHA224 in order to satisfy 'weird' needs from the server
+ * side.
*/
if( ssl->transform_negotiate->ciphersuite_info->mac ==
MBEDTLS_MD_SHA384 )
@@ -3340,8 +3576,10 @@
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index b1028b7..053a11b 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -164,8 +164,7 @@
{
unsigned char hmac_out[COOKIE_MD_OUTLEN];
- if( (size_t)( end - *p ) < COOKIE_HMAC_LEN )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ MBEDTLS_SSL_CHK_BUF_PTR( *p, end, COOKIE_HMAC_LEN );
if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 ||
mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 ||
@@ -195,8 +194,7 @@
if( ctx == NULL || cli_id == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( (size_t)( end - *p ) < COOKIE_LEN )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ MBEDTLS_SSL_CHK_BUF_PTR( *p, end, COOKIE_LEN );
#if defined(MBEDTLS_HAVE_TIME)
t = (unsigned long) mbedtls_time( NULL );
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index bdb79c4..0e0b3de 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -62,6 +62,7 @@
#define mbedtls_free free
#endif
+#include "mbedtls/ssl_internal.h"
#include "mbedtls/ssl_ticket.h"
#include <string.h>
@@ -85,6 +86,19 @@
#define MAX_KEY_BYTES 32 /* 256 bits */
+#define TICKET_KEY_NAME_BYTES 4
+#define TICKET_IV_BYTES 12
+#define TICKET_CRYPT_LEN_BYTES 2
+#define TICKET_AUTH_TAG_BYTES 16
+
+#define TICKET_MIN_LEN ( TICKET_KEY_NAME_BYTES + \
+ TICKET_IV_BYTES + \
+ TICKET_CRYPT_LEN_BYTES + \
+ TICKET_AUTH_TAG_BYTES )
+#define TICKET_ADD_DATA_LEN ( TICKET_KEY_NAME_BYTES + \
+ TICKET_IV_BYTES + \
+ TICKET_CRYPT_LEN_BYTES )
+
/*
* Generate/update a key
*/
@@ -309,6 +323,7 @@
* The key_name, iv, and length of encrypted_state are the additional
* authenticated data.
*/
+
int mbedtls_ssl_ticket_write( void *p_ticket,
const mbedtls_ssl_session *session,
unsigned char *start,
@@ -320,9 +335,9 @@
mbedtls_ssl_ticket_context *ctx = p_ticket;
mbedtls_ssl_ticket_key *key;
unsigned char *key_name = start;
- unsigned char *iv = start + 4;
- unsigned char *state_len_bytes = iv + 12;
- unsigned char *state = state_len_bytes + 2;
+ unsigned char *iv = start + TICKET_KEY_NAME_BYTES;
+ unsigned char *state_len_bytes = iv + TICKET_IV_BYTES;
+ unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES;
unsigned char *tag;
size_t clear_len, ciph_len;
@@ -333,8 +348,7 @@
/* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag,
* in addition to session itself, that will be checked when writing it. */
- if( end - start < 4 + 12 + 2 + 16 )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ MBEDTLS_SSL_CHK_BUF_PTR( start, end, TICKET_MIN_LEN );
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
@@ -348,9 +362,9 @@
*ticket_lifetime = ctx->ticket_lifetime;
- memcpy( key_name, key->name, 4 );
+ memcpy( key_name, key->name, TICKET_KEY_NAME_BYTES );
- if( ( ret = ctx->f_rng( ctx->p_rng, iv, 12 ) ) != 0 )
+ if( ( ret = ctx->f_rng( ctx->p_rng, iv, TICKET_IV_BYTES ) ) != 0 )
goto cleanup;
/* Dump session state */
@@ -366,8 +380,11 @@
/* Encrypt and authenticate */
tag = state + clear_len;
if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx,
- iv, 12, key_name, 4 + 12 + 2,
- state, clear_len, state, &ciph_len, tag, 16 ) ) != 0 )
+ iv, TICKET_IV_BYTES,
+ /* Additional data: key name, IV and length */
+ key_name, TICKET_ADD_DATA_LEN,
+ state, clear_len, state, &ciph_len,
+ tag, TICKET_AUTH_TAG_BYTES ) ) != 0 )
{
goto cleanup;
}
@@ -377,7 +394,7 @@
goto cleanup;
}
- *tlen = 4 + 12 + 2 + 16 + ciph_len;
+ *tlen = TICKET_MIN_LEN + ciph_len;
cleanup:
#if defined(MBEDTLS_THREADING_C)
@@ -416,17 +433,16 @@
mbedtls_ssl_ticket_context *ctx = p_ticket;
mbedtls_ssl_ticket_key *key;
unsigned char *key_name = buf;
- unsigned char *iv = buf + 4;
- unsigned char *enc_len_p = iv + 12;
- unsigned char *ticket = enc_len_p + 2;
+ unsigned char *iv = buf + TICKET_KEY_NAME_BYTES;
+ unsigned char *enc_len_p = iv + TICKET_IV_BYTES;
+ unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES;
unsigned char *tag;
size_t enc_len, clear_len;
if( ctx == NULL || ctx->f_rng == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- /* See mbedtls_ssl_ticket_write() */
- if( len < 4 + 12 + 2 + 16 )
+ if( len < TICKET_MIN_LEN )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
#if defined(MBEDTLS_THREADING_C)
@@ -440,7 +456,7 @@
enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1];
tag = ticket + enc_len;
- if( len != 4 + 12 + 2 + enc_len + 16 )
+ if( len != TICKET_MIN_LEN + enc_len )
{
ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
goto cleanup;
@@ -456,9 +472,13 @@
}
/* Decrypt and authenticate */
- if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, iv, 12,
- key_name, 4 + 12 + 2, ticket, enc_len,
- ticket, &clear_len, tag, 16 ) ) != 0 )
+ if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx,
+ iv, TICKET_IV_BYTES,
+ /* Additional data: key name, IV and length */
+ key_name, TICKET_ADD_DATA_LEN,
+ ticket, enc_len,
+ ticket, &clear_len,
+ tag, TICKET_AUTH_TAG_BYTES ) ) != 0 )
{
if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
ret = MBEDTLS_ERR_SSL_INVALID_MAC;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 44733fb..214628d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -6553,7 +6553,9 @@
cur_len = strlen( *p );
tot_len += cur_len;
- if( cur_len == 0 || cur_len > 255 || tot_len > 65535 )
+ if( ( cur_len == 0 ) ||
+ ( cur_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN ) ||
+ ( tot_len > MBEDTLS_SSL_MAX_ALPN_LIST_LEN ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}