https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0ba5bc40fb00095f0bf94…
commit 0ba5bc40fb00095f0bf9415d912e3a55c5a65198
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Sat Jan 5 11:14:58 2019 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Wed Jan 9 10:47:38 2019 +0100
[MBEDTLS] Update to version 2.7.9. CORE-15280
---
dll/3rdparty/mbedtls/asn1write.c | 26 ++-
dll/3rdparty/mbedtls/bignum.c | 98 ++++++---
dll/3rdparty/mbedtls/cipher.c | 16 +-
dll/3rdparty/mbedtls/cipher_wrap.c | 6 +-
dll/3rdparty/mbedtls/ctr_drbg.c | 82 ++++----
dll/3rdparty/mbedtls/ecp.c | 2 +-
dll/3rdparty/mbedtls/entropy_poll.c | 57 +----
dll/3rdparty/mbedtls/hmac_drbg.c | 93 +++++++--
dll/3rdparty/mbedtls/pkcs12.c | 4 +
dll/3rdparty/mbedtls/pkcs5.c | 17 +-
dll/3rdparty/mbedtls/pkparse.c | 36 ++--
dll/3rdparty/mbedtls/platform.c | 13 +-
dll/3rdparty/mbedtls/rsa.c | 247 +++++++++++++++++-----
dll/3rdparty/mbedtls/ssl_cli.c | 4 +-
dll/3rdparty/mbedtls/ssl_ticket.c | 16 +-
dll/3rdparty/mbedtls/ssl_tls.c | 13 +-
dll/3rdparty/mbedtls/timing.c | 12 +-
dll/3rdparty/mbedtls/x509_crt.c | 267 ++++++++++++------------
sdk/include/reactos/libs/mbedtls/bn_mul.h | 22 +-
sdk/include/reactos/libs/mbedtls/check_config.h | 4 +
sdk/include/reactos/libs/mbedtls/config.h | 2 +-
sdk/include/reactos/libs/mbedtls/ctr_drbg.h | 33 ++-
sdk/include/reactos/libs/mbedtls/hmac_drbg.h | 22 +-
sdk/include/reactos/libs/mbedtls/pkcs12.h | 4 +
sdk/include/reactos/libs/mbedtls/pkcs5.h | 4 +
sdk/include/reactos/libs/mbedtls/ssl.h | 21 +-
sdk/include/reactos/libs/mbedtls/version.h | 8 +-
sdk/include/reactos/libs/mbedtls/x509_crt.h | 39 ++--
28 files changed, 737 insertions(+), 431 deletions(-)
diff --git a/dll/3rdparty/mbedtls/asn1write.c b/dll/3rdparty/mbedtls/asn1write.c
index 00b5e7ad4f..bbcba87ce5 100644
--- a/dll/3rdparty/mbedtls/asn1write.c
+++ b/dll/3rdparty/mbedtls/asn1write.c
@@ -333,14 +333,36 @@ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned
char *start,
return( (int) len );
}
-mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head,
+
+/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(),
+ * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */
+static mbedtls_asn1_named_data *asn1_find_named_data(
+ mbedtls_asn1_named_data *list,
+ const char *oid, size_t len )
+{
+ while( list != NULL )
+ {
+ if( list->oid.len == len &&
+ memcmp( list->oid.p, oid, len ) == 0 )
+ {
+ break;
+ }
+
+ list = list->next;
+ }
+
+ return( list );
+}
+
+mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
+ mbedtls_asn1_named_data **head,
const char *oid, size_t oid_len,
const unsigned char *val,
size_t val_len )
{
mbedtls_asn1_named_data *cur;
- if( ( cur = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
+ if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
{
// Add new entry if not present yet based on OID
//
diff --git a/dll/3rdparty/mbedtls/bignum.c b/dll/3rdparty/mbedtls/bignum.c
index 49441d19b8..7194bf895a 100644
--- a/dll/3rdparty/mbedtls/bignum.c
+++ b/dll/3rdparty/mbedtls/bignum.c
@@ -320,6 +320,10 @@ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
}
+/* Get a specific byte, without range checks. */
+#define GET_BYTE( X, i ) \
+ ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
+
/*
* Set a bit to a specific value of 0 or 1
*/
@@ -703,19 +707,40 @@ cleanup:
/*
* Export X into unsigned binary data, big endian
*/
-int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen )
+int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
+ unsigned char *buf, size_t buflen )
{
- size_t i, j, n;
-
- n = mbedtls_mpi_size( X );
-
- if( buflen < n )
- return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+ size_t stored_bytes = X->n * ciL;
+ size_t bytes_to_copy;
+ unsigned char *p;
+ size_t i;
- memset( buf, 0, buflen );
+ if( stored_bytes < buflen )
+ {
+ /* There is enough space in the output buffer. Write initial
+ * null bytes and record the position at which to start
+ * writing the significant bytes. In this case, the execution
+ * trace of this function does not depend on the value of the
+ * number. */
+ bytes_to_copy = stored_bytes;
+ p = buf + buflen - stored_bytes;
+ memset( buf, 0, buflen - stored_bytes );
+ }
+ else
+ {
+ /* The output buffer is smaller than the allocated size of X.
+ * However X may fit if its leading bytes are zero. */
+ bytes_to_copy = buflen;
+ p = buf;
+ for( i = bytes_to_copy; i < stored_bytes; i++ )
+ {
+ if( GET_BYTE( X, i ) != 0 )
+ return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+ }
+ }
- for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
- buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
+ for( i = 0; i < bytes_to_copy; i++ )
+ p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
return( 0 );
}
@@ -2055,12 +2080,12 @@ cleanup:
/*
* Miller-Rabin pseudo-primality test (HAC 4.24)
*/
-static int mpi_miller_rabin( const mbedtls_mpi *X,
+static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret, count;
- size_t i, j, k, n, s;
+ size_t i, j, k, s;
mbedtls_mpi W, R, T, A, RR;
mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T );
mbedtls_mpi_init( &A );
@@ -2076,27 +2101,12 @@ static int mpi_miller_rabin( const mbedtls_mpi *X,
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
i = mbedtls_mpi_bitlen( X );
- /*
- * HAC, table 4.4
- */
- n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
- ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
- ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
- for( i = 0; i < n; i++ )
+ for( i = 0; i < rounds; i++ )
{
/*
* pick a random A, 1 < A < |X| - 1
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng )
);
-
- if( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 )
- {
- j = mbedtls_mpi_bitlen( &A ) - mbedtls_mpi_bitlen( &W );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j + 1 ) );
- }
- A.p[0] |= 3;
-
count = 0;
do {
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng
) );
@@ -2104,7 +2114,7 @@ static int mpi_miller_rabin( const mbedtls_mpi *X,
j = mbedtls_mpi_bitlen( &A );
k = mbedtls_mpi_bitlen( &W );
if (j > k) {
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j - k ) );
+ A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) *
biL - 1 ) ) - 1;
}
if (count++ > 30) {
@@ -2159,7 +2169,7 @@ cleanup:
/*
* Pseudo-primality test: small factors, then Miller-Rabin
*/
-int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
+static int mpi_is_prime_internal( const mbedtls_mpi *X, int rounds,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
@@ -2185,7 +2195,17 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
return( ret );
}
- return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
+ return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
+}
+
+/*
+ * Pseudo-primality test, error probability 2^-80
+ */
+int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ return mpi_is_prime_internal( X, 40, f_rng, p_rng );
}
/*
@@ -2197,6 +2217,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int
dh_flag,
{
int ret;
size_t k, n;
+ int rounds;
mbedtls_mpi_uint r;
mbedtls_mpi Y;
@@ -2207,6 +2228,13 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int
dh_flag,
n = BITS_TO_LIMBS( nbits );
+ /*
+ * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
+ */
+ rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 :
+ ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 :
+ ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 );
+
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
k = mbedtls_mpi_bitlen( X );
@@ -2218,7 +2246,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int
dh_flag,
if( dh_flag == 0 )
{
- while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
+ while( ( ret = mpi_is_prime_internal( X, rounds, f_rng, p_rng ) ) != 0 )
{
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
goto cleanup;
@@ -2254,8 +2282,10 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int
dh_flag,
*/
if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
( ret = mpi_check_small_factors( &Y ) ) == 0 &&
- ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
- ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
+ ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) )
+ == 0 &&
+ ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) )
+ == 0 )
{
break;
}
diff --git a/dll/3rdparty/mbedtls/cipher.c b/dll/3rdparty/mbedtls/cipher.c
index e36445f975..dfb9cad7f4 100644
--- a/dll/3rdparty/mbedtls/cipher.c
+++ b/dll/3rdparty/mbedtls/cipher.c
@@ -213,9 +213,13 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len )
{
size_t actual_iv_size;
-
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
+ if( NULL == ctx || NULL == ctx->cipher_info )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ else if( NULL == iv && iv_len != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ if( NULL == iv && iv_len == 0 )
+ ctx->iv_size = 0;
/* avoid buffer overflow in ctx->iv */
if( iv_len > MBEDTLS_MAX_IV_LENGTH )
@@ -231,9 +235,11 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
if( actual_iv_size > iv_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
-
- memcpy( ctx->iv, iv, actual_iv_size );
- ctx->iv_size = actual_iv_size;
+ if ( actual_iv_size != 0 )
+ {
+ memcpy( ctx->iv, iv, actual_iv_size );
+ ctx->iv_size = actual_iv_size;
+ }
return( 0 );
}
diff --git a/dll/3rdparty/mbedtls/cipher_wrap.c b/dll/3rdparty/mbedtls/cipher_wrap.c
index 54a81c53c1..94c8be77b0 100644
--- a/dll/3rdparty/mbedtls/cipher_wrap.c
+++ b/dll/3rdparty/mbedtls/cipher_wrap.c
@@ -206,7 +206,7 @@ static const mbedtls_cipher_info_t aes_128_ecb_info = {
MBEDTLS_MODE_ECB,
128,
"AES-128-ECB",
- 16,
+ 0,
0,
16,
&aes_info
@@ -217,7 +217,7 @@ static const mbedtls_cipher_info_t aes_192_ecb_info = {
MBEDTLS_MODE_ECB,
192,
"AES-192-ECB",
- 16,
+ 0,
0,
16,
&aes_info
@@ -228,7 +228,7 @@ static const mbedtls_cipher_info_t aes_256_ecb_info = {
MBEDTLS_MODE_ECB,
256,
"AES-256-ECB",
- 16,
+ 0,
0,
16,
&aes_info
diff --git a/dll/3rdparty/mbedtls/ctr_drbg.c b/dll/3rdparty/mbedtls/ctr_drbg.c
index 7994b53383..f105391cc6 100644
--- a/dll/3rdparty/mbedtls/ctr_drbg.c
+++ b/dll/3rdparty/mbedtls/ctr_drbg.c
@@ -285,9 +285,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
* Crypt counter block
*/
if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
ctx->counter, p ) ) != 0 )
- {
- return( ret );
- }
+ goto exit;
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
}
@@ -299,29 +297,44 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
* Update key and counter
*/
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp,
MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
- {
- return( ret );
- }
+ goto exit;
memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE
);
- return( 0 );
+exit:
+ mbedtls_zeroize( tmp, sizeof( tmp ) );
+ return( ret );
}
-void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
- const unsigned char *additional, size_t add_len )
+int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t add_len )
{
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
+ int ret;
- if( add_len > 0 )
- {
- /* MAX_INPUT would be more logical here, but we have to match
- * block_cipher_df()'s limits since we can't propagate errors */
- if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
- add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
+ if( add_len == 0 )
+ return( 0 );
- block_cipher_df( add_input, additional, add_len );
- ctr_drbg_update_internal( ctx, add_input );
- }
+ if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
+ goto exit;
+ if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
+ goto exit;
+
+exit:
+ mbedtls_zeroize( add_input, sizeof( add_input ) );
+ return( ret );
+}
+
+/* Deprecated function, kept for backward compatibility. */
+void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t add_len )
+{
+ /* MAX_INPUT would be more logical here, but we have to match
+ * block_cipher_df()'s limits since we can't propagate errors */
+ if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
+ add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
+ (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
}
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
@@ -361,20 +374,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
* Reduce to 384 bits
*/
if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
- {
- return( ret );
- }
+ goto exit;
/*
* Update state
*/
if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
- {
- return( ret );
- }
+ goto exit;
ctx->reseed_counter = 1;
- return( 0 );
+exit:
+ mbedtls_zeroize( seed, sizeof( seed ) );
+ return( ret );
}
int mbedtls_ctr_drbg_random_with_add( void *p_rng,
@@ -410,13 +421,9 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
if( add_len > 0 )
{
if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
- {
- return( ret );
- }
+ goto exit;
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
- {
- return( ret );
- }
+ goto exit;
}
while( output_len > 0 )
@@ -432,9 +439,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
* Crypt counter block
*/
if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
ctx->counter, tmp ) ) != 0 )
- {
- return( ret );
- }
+ goto exit;
use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
MBEDTLS_CTR_DRBG_BLOCKSIZE :
output_len;
@@ -447,12 +452,13 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
}
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
- {
- return( ret );
- }
+ goto exit;
ctx->reseed_counter++;
+exit:
+ mbedtls_zeroize( add_input, sizeof( add_input ) );
+ mbedtls_zeroize( tmp, sizeof( tmp ) );
return( 0 );
}
@@ -524,7 +530,7 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
const char
if( fread( buf, 1, n, f ) != n )
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
else
- mbedtls_ctr_drbg_update( ctx, buf, n );
+ ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
fclose( f );
diff --git a/dll/3rdparty/mbedtls/ecp.c b/dll/3rdparty/mbedtls/ecp.c
index bd473604eb..809c5f1a06 100644
--- a/dll/3rdparty/mbedtls/ecp.c
+++ b/dll/3rdparty/mbedtls/ecp.c
@@ -411,7 +411,7 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
}
/*
- * Compare two points lazyly
+ * Compare two points lazily
*/
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q )
diff --git a/dll/3rdparty/mbedtls/entropy_poll.c b/dll/3rdparty/mbedtls/entropy_poll.c
index 7b05a23ac2..c51d0742af 100644
--- a/dll/3rdparty/mbedtls/entropy_poll.c
+++ b/dll/3rdparty/mbedtls/entropy_poll.c
@@ -94,6 +94,7 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output,
size_t len
#include <sys/syscall.h>
#if defined(SYS_getrandom)
#define HAVE_GETRANDOM
+#include <errno.h>
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
{
@@ -103,47 +104,8 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int
flags )
memset( buf, 0, buflen );
#endif
#endif
-
return( syscall( SYS_getrandom, buf, buflen, flags ) );
}
-
-#include <sys/utsname.h>
-/* Check if version is at least 3.17.0 */
-static int check_version_3_17_plus( void )
-{
- int minor;
- struct utsname un;
- const char *ver;
-
- /* Get version information */
- uname(&un);
- ver = un.release;
-
- /* Check major version; assume a single digit */
- if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
- return( -1 );
-
- if( ver[0] - '0' > 3 )
- return( 0 );
-
- /* Ok, so now we know major == 3, check minor.
- * Assume 1 or 2 digits. */
- if( ver[2] < '0' || ver[2] > '9' )
- return( -1 );
-
- minor = ver[2] - '0';
-
- if( ver[3] >= '0' && ver[3] <= '9' )
- minor = 10 * minor + ver[3] - '0';
- else if( ver [3] != '.' )
- return( -1 );
-
- if( minor < 17 )
- return( -1 );
-
- return( 0 );
-}
-static int has_getrandom = -1;
#endif /* SYS_getrandom */
#endif /* __linux__ */
@@ -154,22 +116,21 @@ int mbedtls_platform_entropy_poll( void *data,
{
FILE *file;
size_t read_len;
+ int ret;
((void) data);
#if defined(HAVE_GETRANDOM)
- if( has_getrandom == -1 )
- has_getrandom = ( check_version_3_17_plus() == 0 );
-
- if( has_getrandom )
+ ret = getrandom_wrapper( output, len, 0 );
+ if( ret >= 0 )
{
- int ret;
-
- if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
- return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
-
*olen = ret;
return( 0 );
}
+ else if( errno != ENOSYS )
+ return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+ /* Fall through if the system call isn't known. */
+#else
+ ((void) ret);
#endif /* HAVE_GETRANDOM */
*olen = 0;
diff --git a/dll/3rdparty/mbedtls/hmac_drbg.c b/dll/3rdparty/mbedtls/hmac_drbg.c
index cda64a2713..6adfef7e70 100644
--- a/dll/3rdparty/mbedtls/hmac_drbg.c
+++ b/dll/3rdparty/mbedtls/hmac_drbg.c
@@ -72,29 +72,56 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
/*
* HMAC_DRBG update, using optional additional data (10.1.2.2)
*/
-void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
- const unsigned char *additional, size_t add_len )
+int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t add_len )
{
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
unsigned char sep[1];
unsigned char K[MBEDTLS_MD_MAX_SIZE];
+ int ret;
for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
{
/* Step 1 or 4 */
- mbedtls_md_hmac_reset( &ctx->md_ctx );
- mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 );
+ if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ ctx->V, md_len ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ sep, 1 ) ) != 0 )
+ goto exit;
if( rounds == 2 )
- mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len );
- mbedtls_md_hmac_finish( &ctx->md_ctx, K );
+ {
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ additional, add_len ) ) != 0 )
+ goto exit;
+ }
+ if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
+ goto exit;
/* Step 2 or 5 */
- mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len );
- mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
+ if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ ctx->V, md_len ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
+ goto exit;
}
+
+exit:
+ mbedtls_zeroize( K, sizeof( K ) );
+ return( ret );
+}
+
+void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t add_len )
+{
+ (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
}
/*
@@ -114,10 +141,13 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
* Use the V memory location, which is currently all 0, to initialize the
* MD context with an all-zero key. Then set V to its initial value.
*/
- mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info
) );
+ if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
+ mbedtls_md_get_size( md_info ) ) ) != 0 )
+ return( ret );
memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
- mbedtls_hmac_drbg_update( ctx, data, data_len );
+ if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
+ return( ret );
return( 0 );
}
@@ -130,6 +160,7 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
{
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
size_t seedlen;
+ int ret;
/* III. Check input length */
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
@@ -141,7 +172,8 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
/* IV. Gather entropy_len bytes of entropy for the seed */
- if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
+ if( ( ret = ctx->f_entropy( ctx->p_entropy,
+ seed, ctx->entropy_len ) ) != 0 )
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
seedlen = ctx->entropy_len;
@@ -154,13 +186,16 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
}
/* 2. Update state */
- mbedtls_hmac_drbg_update( ctx, seed, seedlen );
+ if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
+ goto exit;
/* 3. Reset reseed_counter */
ctx->reseed_counter = 1;
+exit:
/* 4. Done */
- return( 0 );
+ mbedtls_zeroize( seed, seedlen );
+ return( ret );
}
/*
@@ -186,7 +221,8 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
* Use the V memory location, which is currently all 0, to initialize the
* MD context with an all-zero key. Then set V to its initial value.
*/
- mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size );
+ if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0
)
+ return( ret );
memset( ctx->V, 0x01, md_size );
ctx->f_entropy = f_entropy;
@@ -279,16 +315,24 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
/* 2. Use additional data if any */
if( additional != NULL && add_len != 0 )
- mbedtls_hmac_drbg_update( ctx, additional, add_len );
+ {
+ if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+ additional, add_len ) ) != 0 )
+ goto exit;
+ }
/* 3, 4, 5. Generate bytes */
while( left != 0 )
{
size_t use_len = left > md_len ? md_len : left;
- mbedtls_md_hmac_reset( &ctx->md_ctx );
- mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
+ if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ ctx->V, md_len ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
+ goto exit;
memcpy( out, ctx->V, use_len );
out += use_len;
@@ -296,13 +340,16 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
}
/* 6. Update */
- mbedtls_hmac_drbg_update( ctx, additional, add_len );
+ if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+ additional, add_len ) ) != 0 )
+ goto exit;
/* 7. Update reseed counter */
ctx->reseed_counter++;
+exit:
/* 8. Done */
- return( 0 );
+ return( ret );
}
/*
@@ -394,7 +441,7 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context
*ctx, const ch
if( fread( buf, 1, n, f ) != n )
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
else
- mbedtls_hmac_drbg_update( ctx, buf, n );
+ ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
fclose( f );
diff --git a/dll/3rdparty/mbedtls/pkcs12.c b/dll/3rdparty/mbedtls/pkcs12.c
index ab813e0824..76b816cfdc 100644
--- a/dll/3rdparty/mbedtls/pkcs12.c
+++ b/dll/3rdparty/mbedtls/pkcs12.c
@@ -54,6 +54,8 @@ static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
mbedtls_asn1_buf *salt, int *iterations )
{
@@ -232,6 +234,8 @@ exit:
return( ret );
}
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
const unsigned char *filler, size_t fill_len )
{
diff --git a/dll/3rdparty/mbedtls/pkcs5.c b/dll/3rdparty/mbedtls/pkcs5.c
index e62d663d25..3b23f99b30 100644
--- a/dll/3rdparty/mbedtls/pkcs5.c
+++ b/dll/3rdparty/mbedtls/pkcs5.c
@@ -56,22 +56,7 @@
#define mbedtls_printf printf
#endif
-#if !defined(MBEDTLS_ASN1_PARSE_C)
-int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
- const unsigned char *pwd, size_t pwdlen,
- const unsigned char *data, size_t datalen,
- unsigned char *output )
-{
- ((void) pbe_params);
- ((void) mode);
- ((void) pwd);
- ((void) pwdlen);
- ((void) data);
- ((void) datalen);
- ((void) output);
- return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
-}
-#else
+#if defined(MBEDTLS_ASN1_PARSE_C)
static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
mbedtls_asn1_buf *salt, int *iterations,
int *keylen, mbedtls_md_type_t *md_type )
diff --git a/dll/3rdparty/mbedtls/pkparse.c b/dll/3rdparty/mbedtls/pkparse.c
index c8da059163..8afe989f77 100644
--- a/dll/3rdparty/mbedtls/pkparse.c
+++ b/dll/3rdparty/mbedtls/pkparse.c
@@ -1304,6 +1304,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
return( 0 );
mbedtls_pk_free( pk );
+ mbedtls_pk_init( pk );
if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH )
{
@@ -1315,39 +1316,42 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
return( 0 );
mbedtls_pk_free( pk );
+ mbedtls_pk_init( pk );
#if defined(MBEDTLS_RSA_C)
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
- if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
- ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
- key, keylen ) ) != 0 )
- {
- mbedtls_pk_free( pk );
- }
- else
+ if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
+ pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) == 0 )
{
return( 0 );
}
+ mbedtls_pk_free( pk );
+ mbedtls_pk_init( pk );
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
-
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
- if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
- ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
- key, keylen ) ) != 0 )
- {
- mbedtls_pk_free( pk );
- }
- else
+ if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
+ pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
+ key, keylen ) == 0 )
{
return( 0 );
}
-
+ mbedtls_pk_free( pk );
#endif /* MBEDTLS_ECP_C */
+ /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
+ * it is ok to leave the PK context initialized but not
+ * freed: It is the caller's responsibility to call pk_init()
+ * before calling this function, and to call pk_free()
+ * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
+ * isn't, this leads to mbedtls_pk_free() being called
+ * twice, once here and once by the caller, but this is
+ * also ok and in line with the mbedtls_pk_free() calls
+ * on failed PEM parsing attempts. */
+
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
}
diff --git a/dll/3rdparty/mbedtls/platform.c b/dll/3rdparty/mbedtls/platform.c
index e1ba90d4ac..d927951762 100644
--- a/dll/3rdparty/mbedtls/platform.c
+++ b/dll/3rdparty/mbedtls/platform.c
@@ -39,7 +39,14 @@ static void mbedtls_zeroize( void *v, size_t n ) {
}
#endif
-#if defined(MBEDTLS_PLATFORM_MEMORY)
+/* The compile time configuration of memory allocation via the macros
+ * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime
+ * configuration via mbedtls_platform_set_calloc_free(). So, omit everything
+ * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */
+#if defined(MBEDTLS_PLATFORM_MEMORY) && \
+ !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \
+ defined(MBEDTLS_PLATFORM_FREE_MACRO) )
+
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
static void *platform_calloc_uninit( size_t n, size_t size )
{
@@ -70,7 +77,9 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t,
size_t ),
mbedtls_free = free_func;
return( 0 );
}
-#endif /* MBEDTLS_PLATFORM_MEMORY */
+#endif /* MBEDTLS_PLATFORM_MEMORY &&
+ !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&
+ defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */
#if defined(_WIN32)
#include <stdarg.h>
diff --git a/dll/3rdparty/mbedtls/rsa.c b/dll/3rdparty/mbedtls/rsa.c
index 6196af215f..e9604e05d6 100644
--- a/dll/3rdparty/mbedtls/rsa.c
+++ b/dll/3rdparty/mbedtls/rsa.c
@@ -1366,6 +1366,97 @@ cleanup:
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PKCS1_V15)
+/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
+ *
+ * \param value The value to analyze.
+ * \return Zero if \p value is zero, otherwise all-bits-one.
+ */
+static unsigned all_or_nothing_int( unsigned value )
+{
+ /* MSVC has a warning about unary minus on unsigned, but this is
+ * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+ return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+/** Check whether a size is out of bounds, without branches.
+ *
+ * This is equivalent to `size > max`, but is likely to be compiled to
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param size Size to check.
+ * \param max Maximum desired value for \p size.
+ * \return \c 0 if `size <= max`.
+ * \return \c 1 if `size > max`.
+ */
+static unsigned size_greater_than( size_t size, size_t max )
+{
+ /* Return the sign bit (1 for negative) of (max - size). */
+ return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
+}
+
+/** Choose between two integer values, without branches.
+ *
+ * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param cond Condition to test.
+ * \param if1 Value to use if \p cond is nonzero.
+ * \param if0 Value to use if \p cond is zero.
+ * \return \c if1 if \p cond is nonzero, otherwise \c if0.
+ */
+static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
+{
+ unsigned mask = all_or_nothing_int( cond );
+ return( ( mask & if1 ) | (~mask & if0 ) );
+}
+
+/** Shift some data towards the left inside a buffer without leaking
+ * the length of the data through side channels.
+ *
+ * `mem_move_to_left(start, total, offset)` is functionally equivalent to
+ * ```
+ * memmove(start, start + offset, total - offset);
+ * memset(start + offset, 0, total - offset);
+ * ```
+ * but it strives to use a memory access pattern (and thus total timing)
+ * that does not depend on \p offset. This timing independence comes at
+ * the expense of performance.
+ *
+ * \param start Pointer to the start of the buffer.
+ * \param total Total size of the buffer.
+ * \param offset Offset from which to copy \p total - \p offset bytes.
+ */
+static void mem_move_to_left( void *start,
+ size_t total,
+ size_t offset )
+{
+ volatile unsigned char *buf = start;
+ size_t i, n;
+ if( total == 0 )
+ return;
+ for( i = 0; i < total; i++ )
+ {
+ unsigned no_op = size_greater_than( total - offset, i );
+ /* The first `total - offset` passes are a no-op. The last
+ * `offset` passes shift the data one byte to the left and
+ * zero out the last byte. */
+ for( n = 0; n < total - 1; n++ )
+ {
+ unsigned char current = buf[n];
+ unsigned char next = buf[n+1];
+ buf[n] = if_int( no_op, current, next );
+ }
+ buf[total-1] = if_int( no_op, buf[total-1], 0 );
+ }
+}
+
/*
* Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
*/
@@ -1375,18 +1466,34 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context
*ctx,
int mode, size_t *olen,
const unsigned char *input,
unsigned char *output,
- size_t output_max_len)
+ size_t output_max_len )
{
int ret;
- size_t ilen, pad_count = 0, i;
- unsigned char *p, bad, pad_done = 0;
+ size_t ilen = ctx->len;
+ size_t i;
+ size_t plaintext_max_size = ( output_max_len > ilen - 11 ?
+ ilen - 11 :
+ output_max_len );
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+ /* The following variables take sensitive values: their value must
+ * not leak into the observable behavior of the function other than
+ * the designated outputs (output, olen, return value). Otherwise
+ * this would open the execution of the function to
+ * side-channel-based variants of the Bleichenbacher padding oracle
+ * attack. Potential side channels include overall timing, memory
+ * access patterns (especially visible to an adversary who has access
+ * to a shared memory cache), and branches (especially visible to
+ * an adversary who has access to a shared code cache or to a shared
+ * branch predictor). */
+ size_t pad_count = 0;
+ unsigned bad = 0;
+ unsigned char pad_done = 0;
+ size_t plaintext_size = 0;
+ unsigned output_too_large;
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- ilen = ctx->len;
-
if( ilen < 16 || ilen > sizeof( buf ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1397,63 +1504,109 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context
*ctx,
if( ret != 0 )
goto cleanup;
- p = buf;
- bad = 0;
-
- /*
- * Check and get padding len in "constant-time"
- */
- bad |= *p++; /* First byte must be 0 */
+ /* Check and get padding length in constant time and constant
+ * memory trace. The first byte must be 0. */
+ bad |= buf[0];
- /* This test does not depend on secret data */
if( mode == MBEDTLS_RSA_PRIVATE )
{
- bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
+ /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
+ * where PS must be at least 8 nonzero bytes. */
+ bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
- /* Get padding len, but always read till end of buffer
- * (minus one, for the 00 byte) */
- for( i = 0; i < ilen - 3; i++ )
+ /* Read the whole buffer. Set pad_done to nonzero if we find
+ * the 0x00 byte and remember the padding length in pad_count. */
+ for( i = 2; i < ilen; i++ )
{
- pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
+ pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
}
-
- p += pad_count;
- bad |= *p++; /* Must be zero */
}
else
{
- bad |= *p++ ^ MBEDTLS_RSA_SIGN;
+ /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
+ * where PS must be at least 8 bytes with the value 0xFF. */
+ bad |= buf[1] ^ MBEDTLS_RSA_SIGN;
- /* Get padding len, but always read till end of buffer
- * (minus one, for the 00 byte) */
- for( i = 0; i < ilen - 3; i++ )
+ /* Read the whole buffer. Set pad_done to nonzero if we find
+ * the 0x00 byte and remember the padding length in pad_count.
+ * If there's a non-0xff byte in the padding, the padding is bad. */
+ for( i = 2; i < ilen; i++ )
{
- pad_done |= ( p[i] != 0xFF );
- pad_count += ( pad_done == 0 );
+ pad_done |= if_int( buf[i], 0, 1 );
+ pad_count += if_int( pad_done, 0, 1 );
+ bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
}
-
- p += pad_count;
- bad |= *p++; /* Must be zero */
}
- bad |= ( pad_count < 8 );
-
- if( bad )
- {
- ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
- goto cleanup;
- }
-
- if( ilen - ( p - buf ) > output_max_len )
- {
- ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
- goto cleanup;
- }
-
- *olen = ilen - (p - buf);
- memcpy( output, p, *olen );
- ret = 0;
+ /* If pad_done is still zero, there's no data, only unfinished padding. */
+ bad |= if_int( pad_done, 0, 1 );
+
+ /* There must be at least 8 bytes of padding. */
+ bad |= size_greater_than( 8, pad_count );
+
+ /* If the padding is valid, set plaintext_size to the number of
+ * remaining bytes after stripping the padding. If the padding
+ * is invalid, avoid leaking this fact through the size of the
+ * output: use the maximum message size that fits in the output
+ * buffer. Do it without branches to avoid leaking the padding
+ * validity through timing. RSA keys are small enough that all the
+ * size_t values involved fit in unsigned int. */
+ plaintext_size = if_int( bad,
+ (unsigned) plaintext_max_size,
+ (unsigned) ( ilen - pad_count - 3 ) );
+
+ /* Set output_too_large to 0 if the plaintext fits in the output
+ * buffer and to 1 otherwise. */
+ output_too_large = size_greater_than( plaintext_size,
+ plaintext_max_size );
+
+ /* Set ret without branches to avoid timing attacks. Return:
+ * - INVALID_PADDING if the padding is bad (bad != 0).
+ * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
+ * plaintext does not fit in the output buffer.
+ * - 0 if the padding is correct. */
+ ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
+ if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
+ 0 ) );
+
+ /* If the padding is bad or the plaintext is too large, zero the
+ * data that we're about to copy to the output buffer.
+ * We need to copy the same amount of data
+ * from the same buffer whether the padding is good or not to
+ * avoid leaking the padding validity through overall timing or
+ * through memory or cache access patterns. */
+ bad = all_or_nothing_int( bad | output_too_large );
+ for( i = 11; i < ilen; i++ )
+ buf[i] &= ~bad;
+
+ /* If the plaintext is too large, truncate it to the buffer size.
+ * Copy anyway to avoid revealing the length through timing, because
+ * revealing the length is as bad as revealing the padding validity
+ * for a Bleichenbacher attack. */
+ plaintext_size = if_int( output_too_large,
+ (unsigned) plaintext_max_size,
+ (unsigned) plaintext_size );
+
+ /* Move the plaintext to the leftmost position where it can start in
+ * the working buffer, i.e. make it start plaintext_max_size from
+ * the end of the buffer. Do this with a memory access trace that
+ * does not depend on the plaintext size. After this move, the
+ * starting location of the plaintext is no longer sensitive
+ * information. */
+ mem_move_to_left( buf + ilen - plaintext_max_size,
+ plaintext_max_size,
+ plaintext_max_size - plaintext_size );
+
+ /* Finally copy the decrypted plaintext plus trailing zeros
+ * into the output buffer. */
+ memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
+
+ /* Report the amount of data we copied to the output buffer. In case
+ * of errors (bad padding or output too large), the value of *olen
+ * when this function returns is not specified. Making it equivalent
+ * to the good case limits the risks of leaking the padding validity. */
+ *olen = plaintext_size;
cleanup:
mbedtls_zeroize( buf, sizeof( buf ) );
diff --git a/dll/3rdparty/mbedtls/ssl_cli.c b/dll/3rdparty/mbedtls/ssl_cli.c
index 5a6a482d61..2355d6544d 100644
--- a/dll/3rdparty/mbedtls/ssl_cli.c
+++ b/dll/3rdparty/mbedtls/ssl_cli.c
@@ -2093,7 +2093,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
*
* opaque psk_identity_hint<0..2^16-1>;
*/
- if( (*p) > end - 2 )
+ if( end - (*p) < 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
"(psk_identity_hint length)" ) );
@@ -2102,7 +2102,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
len = (*p)[0] << 8 | (*p)[1];
*p += 2;
- if( (*p) > end - len )
+ if( end - (*p) < (int) len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
"(psk_identity_hint length)" ) );
diff --git a/dll/3rdparty/mbedtls/ssl_ticket.c b/dll/3rdparty/mbedtls/ssl_ticket.c
index 22f114e78c..fe221ffbba 100644
--- a/dll/3rdparty/mbedtls/ssl_ticket.c
+++ b/dll/3rdparty/mbedtls/ssl_ticket.c
@@ -103,7 +103,7 @@ static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx )
uint32_t current_time = (uint32_t) mbedtls_time( NULL );
uint32_t key_time = ctx->keys[ctx->active].generation_time;
- if( current_time > key_time &&
+ if( current_time >= key_time &&
current_time - key_time < ctx->ticket_lifetime )
{
return( 0 );
@@ -194,9 +194,9 @@ static int ssl_save_session( const mbedtls_ssl_session *session,
if( left < 3 + cert_len )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- *p++ = (unsigned char)( cert_len >> 16 & 0xFF );
- *p++ = (unsigned char)( cert_len >> 8 & 0xFF );
- *p++ = (unsigned char)( cert_len & 0xFF );
+ *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
+ *p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF );
+ *p++ = (unsigned char)( ( cert_len ) & 0xFF );
if( session->peer_cert != NULL )
memcpy( p, session->peer_cert->raw.p, cert_len );
@@ -221,14 +221,14 @@ static int ssl_load_session( mbedtls_ssl_session *session,
size_t cert_len;
#endif /* MBEDTLS_X509_CRT_PARSE_C */
- if( p + sizeof( mbedtls_ssl_session ) > end )
+ if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
memcpy( session, p, sizeof( mbedtls_ssl_session ) );
p += sizeof( mbedtls_ssl_session );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( p + 3 > end )
+ if( 3 > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
@@ -242,7 +242,7 @@ static int ssl_load_session( mbedtls_ssl_session *session,
{
int ret;
- if( p + cert_len > end )
+ if( cert_len > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
@@ -253,7 +253,7 @@ static int ssl_load_session( mbedtls_ssl_session *session,
mbedtls_x509_crt_init( session->peer_cert );
if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
- p, cert_len ) ) != 0 )
+ p, cert_len ) ) != 0 )
{
mbedtls_x509_crt_free( session->peer_cert );
mbedtls_free( session->peer_cert );
diff --git a/dll/3rdparty/mbedtls/ssl_tls.c b/dll/3rdparty/mbedtls/ssl_tls.c
index 6f5762bdf0..c588a97ba6 100644
--- a/dll/3rdparty/mbedtls/ssl_tls.c
+++ b/dll/3rdparty/mbedtls/ssl_tls.c
@@ -2133,13 +2133,13 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
correct = 0;
}
auth_done++;
-
- /*
- * Finally check the correct flag
- */
- if( correct == 0 )
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
}
+
+ /*
+ * Finally check the correct flag
+ */
+ if( correct == 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
#endif /* SSL_SOME_MODES_USE_MAC */
/* Make extra sure authentication was performed, exactly once */
@@ -3237,6 +3237,7 @@ static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl
)
memcpy( ssl->in_msg, ssl->handshake->hs_msg, ssl->in_hslen );
+ mbedtls_zeroize( ssl->handshake->hs_msg, ssl->in_hslen );
mbedtls_free( ssl->handshake->hs_msg );
ssl->handshake->hs_msg = NULL;
diff --git a/dll/3rdparty/mbedtls/timing.c b/dll/3rdparty/mbedtls/timing.c
index 8af90d1e36..9f9e98b413 100644
--- a/dll/3rdparty/mbedtls/timing.c
+++ b/dll/3rdparty/mbedtls/timing.c
@@ -53,6 +53,7 @@
#include <windows.h>
#include <winbase.h>
+#include <process.h>
struct _hr_time
{
@@ -268,18 +269,17 @@ unsigned long mbedtls_timing_get_timer( struct
mbedtls_timing_hr_time *val, int
/* It's OK to use a global because alarm() is supposed to be global anyway */
static DWORD alarmMs;
-static DWORD WINAPI TimerProc( LPVOID TimerContext )
+static void TimerProc( void *TimerContext )
{
- ((void) TimerContext);
+ (void) TimerContext;
Sleep( alarmMs );
mbedtls_timing_alarmed = 1;
- return( TRUE );
+ /* _endthread will be called implicitly on return
+ * That ensures execution of thread funcition's epilogue */
}
void mbedtls_set_alarm( int seconds )
{
- DWORD ThreadId;
-
if( seconds == 0 )
{
/* No need to create a thread for this simple case.
@@ -290,7 +290,7 @@ void mbedtls_set_alarm( int seconds )
mbedtls_timing_alarmed = 0;
alarmMs = seconds * 1000;
- CloseHandle( CreateThread( NULL, 0, TimerProc, NULL, 0, &ThreadId ) );
+ (void) _beginthread( TimerProc, 0, NULL );
}
#else /* _WIN32 && !EFIX64 && !EFI32 */
diff --git a/dll/3rdparty/mbedtls/x509_crt.c b/dll/3rdparty/mbedtls/x509_crt.c
index 8c6d65de6d..1a493ddcbb 100644
--- a/dll/3rdparty/mbedtls/x509_crt.c
+++ b/dll/3rdparty/mbedtls/x509_crt.c
@@ -42,7 +42,6 @@
#include "mbedtls/x509_crt.h"
#include "mbedtls/oid.h"
-#include <stdio.h>
#include <string.h>
#if defined(MBEDTLS_PEM_PARSE_C)
@@ -52,6 +51,7 @@
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
+#include <stdio.h>
#include <stdlib.h>
#define mbedtls_free free
#define mbedtls_calloc calloc
@@ -1365,6 +1365,135 @@ static int x509_info_ext_key_usage( char **buf, size_t *size,
return( 0 );
}
+/*
+ * Like memcmp, but case-insensitive and always returns -1 if different
+ */
+static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
+{
+ size_t i;
+ unsigned char diff;
+ const unsigned char *n1 = s1, *n2 = s2;
+
+ for( i = 0; i < len; i++ )
+ {
+ diff = n1[i] ^ n2[i];
+
+ if( diff == 0 )
+ continue;
+
+ if( diff == 32 &&
+ ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
+ ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
+ {
+ continue;
+ }
+
+ return( -1 );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Return 0 if name matches wildcard, -1 otherwise
+ */
+static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name )
+{
+ size_t i;
+ size_t cn_idx = 0, cn_len = strlen( cn );
+
+ if( name->len < 3 || name->p[0] != '*' || name->p[1] !=
'.' )
+ return( 0 );
+
+ for( i = 0; i < cn_len; ++i )
+ {
+ if( cn[i] == '.' )
+ {
+ cn_idx = i;
+ break;
+ }
+ }
+
+ if( cn_idx == 0 )
+ return( -1 );
+
+ if( cn_len - cn_idx == name->len - 1 &&
+ x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
+ {
+ return( 0 );
+ }
+
+ return( -1 );
+}
+
+/*
+ * Compare two X.509 strings, case-insensitive, and allowing for some encoding
+ * variations (but not all).
+ *
+ * Return 0 if equal, -1 otherwise.
+ */
+static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
+{
+ if( a->tag == b->tag &&
+ a->len == b->len &&
+ memcmp( a->p, b->p, b->len ) == 0 )
+ {
+ return( 0 );
+ }
+
+ if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag ==
MBEDTLS_ASN1_PRINTABLE_STRING ) &&
+ ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag ==
MBEDTLS_ASN1_PRINTABLE_STRING ) &&
+ a->len == b->len &&
+ x509_memcasecmp( a->p, b->p, b->len ) == 0 )
+ {
+ return( 0 );
+ }
+
+ return( -1 );
+}
+
+/*
+ * Compare two X.509 Names (aka rdnSequence).
+ *
+ * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
+ * we sometimes return unequal when the full algorithm would return equal,
+ * but never the other way. (In particular, we don't do Unicode normalisation
+ * or space folding.)
+ *
+ * Return 0 if equal, -1 otherwise.
+ */
+static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
+{
+ /* Avoid recursion, it might not be optimised by the compiler */
+ while( a != NULL || b != NULL )
+ {
+ if( a == NULL || b == NULL )
+ return( -1 );
+
+ /* type */
+ if( a->oid.tag != b->oid.tag ||
+ a->oid.len != b->oid.len ||
+ memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
+ {
+ return( -1 );
+ }
+
+ /* value */
+ if( x509_string_cmp( &a->val, &b->val ) != 0 )
+ return( -1 );
+
+ /* structure of the list of sets */
+ if( a->next_merged != b->next_merged )
+ return( -1 );
+
+ a = a->next;
+ b = b->next;
+ }
+
+ /* a == NULL == b */
+ return( 0 );
+}
+
/*
* Return an informational string about the certificate.
*/
@@ -1657,9 +1786,7 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt,
mbedtls_x509_crt *ca,
while( crl_list != NULL )
{
if( crl_list->version == 0 ||
- crl_list->issuer_raw.len != ca->subject_raw.len ||
- memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
- crl_list->issuer_raw.len ) != 0 )
+ x509_name_cmp( &crl_list->issuer, &ca->subject ) != 0 )
{
crl_list = crl_list->next;
continue;
@@ -1669,7 +1796,8 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt,
mbedtls_x509_crt *ca,
* Check if the CA is configured to sign CRLs
*/
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
- if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
+ if( mbedtls_x509_crt_check_key_usage( ca,
+ MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
{
flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
break;
@@ -1729,135 +1857,6 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt,
mbedtls_x509_crt *ca,
}
#endif /* MBEDTLS_X509_CRL_PARSE_C */
-/*
- * Like memcmp, but case-insensitive and always returns -1 if different
- */
-static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
-{
- size_t i;
- unsigned char diff;
- const unsigned char *n1 = s1, *n2 = s2;
-
- for( i = 0; i < len; i++ )
- {
- diff = n1[i] ^ n2[i];
-
- if( diff == 0 )
- continue;
-
- if( diff == 32 &&
- ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
- ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
- {
- continue;
- }
-
- return( -1 );
- }
-
- return( 0 );
-}
-
-/*
- * Return 0 if name matches wildcard, -1 otherwise
- */
-static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name )
-{
- size_t i;
- size_t cn_idx = 0, cn_len = strlen( cn );
-
- if( name->len < 3 || name->p[0] != '*' || name->p[1] !=
'.' )
- return( 0 );
-
- for( i = 0; i < cn_len; ++i )
- {
- if( cn[i] == '.' )
- {
- cn_idx = i;
- break;
- }
- }
-
- if( cn_idx == 0 )
- return( -1 );
-
- if( cn_len - cn_idx == name->len - 1 &&
- x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
- {
- return( 0 );
- }
-
- return( -1 );
-}
-
-/*
- * Compare two X.509 strings, case-insensitive, and allowing for some encoding
- * variations (but not all).
- *
- * Return 0 if equal, -1 otherwise.
- */
-static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
-{
- if( a->tag == b->tag &&
- a->len == b->len &&
- memcmp( a->p, b->p, b->len ) == 0 )
- {
- return( 0 );
- }
-
- if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag ==
MBEDTLS_ASN1_PRINTABLE_STRING ) &&
- ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag ==
MBEDTLS_ASN1_PRINTABLE_STRING ) &&
- a->len == b->len &&
- x509_memcasecmp( a->p, b->p, b->len ) == 0 )
- {
- return( 0 );
- }
-
- return( -1 );
-}
-
-/*
- * Compare two X.509 Names (aka rdnSequence).
- *
- * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
- * we sometimes return unequal when the full algorithm would return equal,
- * but never the other way. (In particular, we don't do Unicode normalisation
- * or space folding.)
- *
- * Return 0 if equal, -1 otherwise.
- */
-static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
-{
- /* Avoid recursion, it might not be optimised by the compiler */
- while( a != NULL || b != NULL )
- {
- if( a == NULL || b == NULL )
- return( -1 );
-
- /* type */
- if( a->oid.tag != b->oid.tag ||
- a->oid.len != b->oid.len ||
- memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
- {
- return( -1 );
- }
-
- /* value */
- if( x509_string_cmp( &a->val, &b->val ) != 0 )
- return( -1 );
-
- /* structure of the list of sets */
- if( a->next_merged != b->next_merged )
- return( -1 );
-
- a = a->next;
- b = b->next;
- }
-
- /* a == NULL == b */
- return( 0 );
-}
-
/*
* Check if 'parent' is a suitable parent (signing CA) for 'child'.
* Return 0 if yes, -1 if not.
diff --git a/sdk/include/reactos/libs/mbedtls/bn_mul.h
b/sdk/include/reactos/libs/mbedtls/bn_mul.h
index ff0c9fe235..34ff50fb07 100644
--- a/sdk/include/reactos/libs/mbedtls/bn_mul.h
+++ b/sdk/include/reactos/libs/mbedtls/bn_mul.h
@@ -172,19 +172,19 @@
#define MULADDC_INIT \
asm( \
- "xorq %%r8, %%r8 \n\t"
+ "xorq %%r8, %%r8\n"
#define MULADDC_CORE \
- "movq (%%rsi), %%rax \n\t" \
- "mulq %%rbx \n\t" \
- "addq $8, %%rsi \n\t" \
- "addq %%rcx, %%rax \n\t" \
- "movq %%r8, %%rcx \n\t" \
- "adcq $0, %%rdx \n\t" \
- "nop \n\t" \
- "addq %%rax, (%%rdi) \n\t" \
- "adcq %%rdx, %%rcx \n\t" \
- "addq $8, %%rdi \n\t"
+ "movq (%%rsi), %%rax\n" \
+ "mulq %%rbx\n" \
+ "addq $8, %%rsi\n" \
+ "addq %%rcx, %%rax\n" \
+ "movq %%r8, %%rcx\n" \
+ "adcq $0, %%rdx\n" \
+ "nop \n" \
+ "addq %%rax, (%%rdi)\n" \
+ "adcq %%rdx, %%rcx\n" \
+ "addq $8, %%rdi\n"
#define MULADDC_STOP \
: "+c" (c), "+D" (d), "+S" (s) \
diff --git a/sdk/include/reactos/libs/mbedtls/check_config.h
b/sdk/include/reactos/libs/mbedtls/check_config.h
index 08a27629e8..564dd4ceb1 100644
--- a/sdk/include/reactos/libs/mbedtls/check_config.h
+++ b/sdk/include/reactos/libs/mbedtls/check_config.h
@@ -124,6 +124,10 @@
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
+#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
+#endif
+
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA256_C))
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
diff --git a/sdk/include/reactos/libs/mbedtls/config.h
b/sdk/include/reactos/libs/mbedtls/config.h
index e151ed9a94..912b5564c5 100644
--- a/sdk/include/reactos/libs/mbedtls/config.h
+++ b/sdk/include/reactos/libs/mbedtls/config.h
@@ -1190,7 +1190,7 @@
/**
* \def MBEDTLS_SSL_RENEGOTIATION
*
- * Disable support for TLS renegotiation.
+ * Enable support for TLS renegotiation.
*
* The two main uses of renegotiation are (1) refresh keys on long-lived
* connections and (2) client authentication after the initial handshake.
diff --git a/sdk/include/reactos/libs/mbedtls/ctr_drbg.h
b/sdk/include/reactos/libs/mbedtls/ctr_drbg.h
index c9ec76ac67..dedce771a9 100644
--- a/sdk/include/reactos/libs/mbedtls/ctr_drbg.h
+++ b/sdk/include/reactos/libs/mbedtls/ctr_drbg.h
@@ -229,14 +229,37 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
*
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with.
- * \param add_len Length of \p additional data.
+ * \param add_len Length of \p additional in bytes. This must be at
+ * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
+ * \p add_len is more than
+ * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ * \return An error from the underlying AES cipher on failure.
+ */
+int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t add_len );
+
+/**
+ * \brief This function updates the state of the CTR_DRBG context.
*
- * \note If \p add_len is greater than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT,
- * only the first #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
- * The remaining Bytes are silently discarded.
+ * \warning This function cannot report errors. You should use
+ * mbedtls_ctr_drbg_update_ret() instead.
+ *
+ * \note If \p add_len is greater than
+ * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
+ * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
+ * The remaining Bytes are silently discarded.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param additional The data to update the state with.
+ * \param add_len Length of \p additional data.
*/
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
- const unsigned char *additional, size_t add_len );
+ const unsigned char *additional,
+ size_t add_len );
/**
* \brief This function updates a CTR_DRBG instance with additional
diff --git a/sdk/include/reactos/libs/mbedtls/hmac_drbg.h
b/sdk/include/reactos/libs/mbedtls/hmac_drbg.h
index f7db73ffd4..91b1dbda9e 100644
--- a/sdk/include/reactos/libs/mbedtls/hmac_drbg.h
+++ b/sdk/include/reactos/libs/mbedtls/hmac_drbg.h
@@ -197,12 +197,32 @@ void mbedtls_hmac_drbg_set_reseed_interval(
mbedtls_hmac_drbg_context *ctx,
* \param additional Additional data to update state with, or NULL
* \param add_len Length of additional data, or 0
*
+ * \return \c 0 on success, or an error from the underlying
+ * hash calculation.
+ *
* \note Additional data is optional, pass NULL and 0 as second
* third argument if no additional data is being used.
*/
-void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
+int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
+/**
+ * \brief HMAC_DRBG update state
+ *
+ * \warning This function cannot report errors. You should use
+ * mbedtls_hmac_drbg_update_ret() instead.
+ *
+ * \param ctx HMAC_DRBG context
+ * \param additional Additional data to update state with, or NULL
+ * \param add_len Length of additional data, or 0
+ *
+ * \note Additional data is optional, pass NULL and 0 as second
+ * third argument if no additional data is being used.
+ */
+void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t add_len );
+
/**
* \brief HMAC_DRBG reseeding (extracts data from entropy source)
*
diff --git a/sdk/include/reactos/libs/mbedtls/pkcs12.h
b/sdk/include/reactos/libs/mbedtls/pkcs12.h
index f2230fa9b9..1b6f449a0b 100644
--- a/sdk/include/reactos/libs/mbedtls/pkcs12.h
+++ b/sdk/include/reactos/libs/mbedtls/pkcs12.h
@@ -48,6 +48,8 @@
extern "C" {
#endif
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
/**
* \brief PKCS12 Password Based function (encryption / decryption)
* for pbeWithSHAAnd128BitRC4
@@ -89,6 +91,8 @@ int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *input, size_t len,
unsigned char *output );
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
/**
* \brief The PKCS#12 derivation function uses a password and a salt
* to produce pseudo-random bits for a particular "purpose".
diff --git a/sdk/include/reactos/libs/mbedtls/pkcs5.h
b/sdk/include/reactos/libs/mbedtls/pkcs5.h
index 7b6acf5800..ffd729fdac 100644
--- a/sdk/include/reactos/libs/mbedtls/pkcs5.h
+++ b/sdk/include/reactos/libs/mbedtls/pkcs5.h
@@ -46,6 +46,8 @@
extern "C" {
#endif
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
/**
* \brief PKCS#5 PBES2 function
*
@@ -64,6 +66,8 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *data, size_t datalen,
unsigned char *output );
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
/**
* \brief PKCS#5 PBKDF2 using HMAC
*
diff --git a/sdk/include/reactos/libs/mbedtls/ssl.h
b/sdk/include/reactos/libs/mbedtls/ssl.h
index bbb8d98787..01387777f8 100644
--- a/sdk/include/reactos/libs/mbedtls/ssl.h
+++ b/sdk/include/reactos/libs/mbedtls/ssl.h
@@ -1620,6 +1620,14 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
* whether it matches those preferences - the server can then
* decide what it wants to do with it.
*
+ * \note The provided \p pk_key needs to match the public key in the
+ * first certificate in \p own_cert, or all handshakes using
+ * that certificate will fail. It is your responsibility
+ * to ensure that; this function will not perform any check.
+ * You may use mbedtls_pk_check_pair() in order to perform
+ * this check yourself, but be aware that this function can
+ * be computationally expensive on some key types.
+ *
* \param conf SSL configuration
* \param own_cert own public certificate chain
* \param pk_key own private key
@@ -2289,13 +2297,14 @@ size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl
);
/**
* \brief Return the result of the certificate verification
*
- * \param ssl SSL context
+ * \param ssl The SSL context to use.
*
- * \return 0 if successful,
- * -1 if result is not available (eg because the handshake was
- * aborted too early), or
- * a combination of BADCERT_xxx and BADCRL_xxx flags, see
- * x509.h
+ * \return \c 0 if the certificate verification was successful.
+ * \return \c -1u if the result is not available. This may happen
+ * e.g. if the handshake aborts early, or a verification
+ * callback returned a fatal error.
+ * \return A bitwise combination of \c MBEDTLS_X509_BADCERT_XXX
+ * and \c MBEDTLS_X509_BADCRL_XXX failure flags; see x509.h.
*/
uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl );
diff --git a/sdk/include/reactos/libs/mbedtls/version.h
b/sdk/include/reactos/libs/mbedtls/version.h
index de6018afe6..ea1568fbdb 100644
--- a/sdk/include/reactos/libs/mbedtls/version.h
+++ b/sdk/include/reactos/libs/mbedtls/version.h
@@ -42,16 +42,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 7
-#define MBEDTLS_VERSION_PATCH 6
+#define MBEDTLS_VERSION_PATCH 9
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x02070600
-#define MBEDTLS_VERSION_STRING "2.7.6"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.7.6"
+#define MBEDTLS_VERSION_NUMBER 0x02070900
+#define MBEDTLS_VERSION_STRING "2.7.9"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.7.9"
#if defined(MBEDTLS_VERSION_C)
diff --git a/sdk/include/reactos/libs/mbedtls/x509_crt.h
b/sdk/include/reactos/libs/mbedtls/x509_crt.h
index 3aa485ff6c..d2dd608f6e 100644
--- a/sdk/include/reactos/libs/mbedtls/x509_crt.h
+++ b/sdk/include/reactos/libs/mbedtls/x509_crt.h
@@ -177,19 +177,34 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const
unsigned char *bu
size_t buflen );
/**
- * \brief Parse one or more certificates and add them
- * to the chained list. Parses permissively. If some
- * certificates can be parsed, the result is the number
- * of failed certificates it encountered. If none complete
- * correctly, the first error is returned.
+ * \brief Parse one DER-encoded or one or more concatenated PEM-encoded
+ * certificates and add them to the chained list.
+ *
+ * For CRTs in PEM encoding, the function parses permissively:
+ * if at least one certificate can be parsed, the function
+ * returns the number of certificates for which parsing failed
+ * (hence \c 0 if all certificates were parsed successfully).
+ * If no certificate could be parsed, the function returns
+ * the first (negative) error encountered during parsing.
+ *
+ * PEM encoded certificates may be interleaved by other data
+ * such as human readable descriptions of their content, as
+ * long as the certificates are enclosed in the PEM specific
+ * '-----{BEGIN/END} CERTIFICATE-----' delimiters.
+ *
+ * \param chain The chain to which to add the parsed certificates.
+ * \param buf The buffer holding the certificate data in PEM or DER format.
+ * For certificates in PEM encoding, this may be a concatenation
+ * of multiple certificates; for DER encoding, the buffer must
+ * comprise exactly one certificate.
+ * \param buflen The size of \p buf, including the terminating \c NULL byte
+ * in case of PEM encoded data.
+ *
+ * \return \c 0 if all certificates were parsed successfully.
+ * \return The (positive) number of certificates that couldn't
+ * be parsed if parsing was partly successful (see above).
+ * \return A negative X509 or PEM error code otherwise.
*
- * \param chain points to the start of the chain
- * \param buf buffer holding the certificate data in PEM or DER format
- * \param buflen size of the buffer
- * (including the terminating null byte for PEM data)
- *
- * \return 0 if all certificates parsed successfully, a positive number
- * if partly successful or a specific X509 or PEM error code
*/
int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t
buflen );