https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a01a8faa603f347cab19dfc0c4ae4df1fe99bd28

commit a01a8faa603f347cab19dfc0c4ae4df1fe99bd28
Author:     Thomas Faber <[email protected]>
AuthorDate: Sat Sep 11 20:10:19 2021 -0400
Commit:     Thomas Faber <[email protected]>
CommitDate: Sun Sep 12 10:49:55 2021 -0400

    [MBEDTLS] Update to version 2.7.19. CORE-17252
---
 dll/3rdparty/mbedtls/base64.c                  | 131 ++++++++++++++++++++++---
 dll/3rdparty/mbedtls/bignum.c                  |   6 ++
 dll/3rdparty/mbedtls/ctr_drbg.c                |  16 +--
 dll/3rdparty/mbedtls/entropy.c                 |   7 +-
 dll/3rdparty/mbedtls/hmac_drbg.c               |  20 ++--
 dll/3rdparty/mbedtls/net_sockets.c             |   7 ++
 dll/3rdparty/mbedtls/pkwrite.c                 |  22 ++---
 dll/3rdparty/mbedtls/rsa.c                     |  31 +++---
 dll/3rdparty/mbedtls/threading.c               |   6 ++
 dll/3rdparty/mbedtls/version_features.c        |   3 +
 media/doc/3rd Party Files.txt                  |   2 +-
 sdk/include/reactos/libs/mbedtls/config.h      |  17 ++++
 sdk/include/reactos/libs/mbedtls/ctr_drbg.h    |  50 +++++++++-
 sdk/include/reactos/libs/mbedtls/entropy.h     |   6 +-
 sdk/include/reactos/libs/mbedtls/hmac_drbg.h   |  63 +++++++++++-
 sdk/include/reactos/libs/mbedtls/net_sockets.h |  14 ++-
 sdk/include/reactos/libs/mbedtls/rsa.h         |   6 +-
 sdk/include/reactos/libs/mbedtls/threading.h   |   3 +
 sdk/include/reactos/libs/mbedtls/version.h     |   8 +-
 19 files changed, 352 insertions(+), 66 deletions(-)

diff --git a/dll/3rdparty/mbedtls/base64.c b/dll/3rdparty/mbedtls/base64.c
index bfafb05353c..692e11e3fae 100644
--- a/dll/3rdparty/mbedtls/base64.c
+++ b/dll/3rdparty/mbedtls/base64.c
@@ -96,6 +96,99 @@ static const unsigned char base64_dec_map[128] =
 
 #define BASE64_SIZE_T_MAX   ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
 
+/*
+ * Constant flow conditional assignment to unsigned char
+ */
+static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const 
unsigned char * const src,
+                                       unsigned char condition )
+{
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * 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
+
+    /* Generate bitmask from condition, mask will either be 0xFF or 0 */
+    unsigned char mask = ( condition | -condition );
+    mask >>= 7;
+    mask = -mask;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
+}
+
+/*
+ * Constant flow conditional assignment to uint_32
+ */
+static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t 
src,
+                                       uint32_t condition )
+{
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * 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
+
+    /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
+    uint32_t mask = ( condition | -condition );
+    mask >>= 31;
+    mask = -mask;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    *dest = ( src & mask ) | ( ( *dest ) & ~mask );
+}
+
+/*
+ * Constant flow check for equality
+ */
+static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
+{
+    size_t difference = in_a ^ in_b;
+
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * 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
+
+    difference |= -difference;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    /* cope with the varying size of size_t per platform */
+    difference >>= ( sizeof( difference ) * 8 - 1 );
+
+    return (unsigned char) ( 1 ^ difference );
+}
+
+/*
+ * Constant flow lookup into table.
+ */
+static unsigned char mbedtls_base64_table_lookup( const unsigned char * const 
table,
+                                                 const size_t table_size, 
const size_t table_index )
+{
+    size_t i;
+    unsigned char result = 0;
+
+    for( i = 0; i < table_size; ++i )
+    {
+        mbedtls_base64_cond_assign_uchar( &result, &table[i], 
mbedtls_base64_eq( i, table_index ) );
+    }
+
+    return result;
+}
+
 /*
  * Encode a buffer into base64 format
  */
@@ -136,10 +229,17 @@ int mbedtls_base64_encode( unsigned char *dst, size_t 
dlen, size_t *olen,
         C2 = *src++;
         C3 = *src++;
 
-        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
-        *p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F];
-        *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
-        *p++ = base64_enc_map[C3 & 0x3F];
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( 
base64_enc_map ),
+                                            ( ( C1 >> 2 ) & 0x3F ) );
+
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( 
base64_enc_map ),
+                                            ( ( ( ( C1 &  3 ) << 4 ) + ( C2 >> 
4 ) ) & 0x3F ) );
+
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( 
base64_enc_map ),
+                                            ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 
6 ) ) & 0x3F ) );
+
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( 
base64_enc_map ),
+                                            ( C3 & 0x3F ) );
     }
 
     if( i < slen )
@@ -147,11 +247,15 @@ int mbedtls_base64_encode( unsigned char *dst, size_t 
dlen, size_t *olen,
         C1 = *src++;
         C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
 
-        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
-        *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( 
base64_enc_map ),
+                                            ( ( C1 >> 2 ) & 0x3F ) );
+
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( 
base64_enc_map ),
+                                            ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 
4 ) ) & 0x3F ) );
 
         if( ( i + 1 ) < slen )
-             *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
+             *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( 
base64_enc_map ),
+                                                 ( ( ( C2 & 15 ) << 2 ) & 0x3F 
) );
         else *p++ = '=';
 
         *p++ = '=';
@@ -172,6 +276,7 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, 
size_t *olen,
     size_t i, n;
     uint32_t j, x;
     unsigned char *p;
+    unsigned char dec_map_lookup;
 
     /* First pass: check for validity and get output length */
     for( i = n = j = 0; i < slen; i++ )
@@ -202,10 +307,12 @@ int mbedtls_base64_decode( unsigned char *dst, size_t 
dlen, size_t *olen,
         if( src[i] == '=' && ++j > 2 )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
-        if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
+        dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( 
base64_dec_map ), src[i] );
+
+        if( src[i] > 127 || dec_map_lookup == 127 )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
-        if( base64_dec_map[src[i]] < 64 && j != 0 )
+        if( dec_map_lookup < 64 && j != 0 )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
         n++;
@@ -235,8 +342,10 @@ int mbedtls_base64_decode( unsigned char *dst, size_t 
dlen, size_t *olen,
         if( *src == '\r' || *src == '\n' || *src == ' ' )
             continue;
 
-        j -= ( base64_dec_map[*src] == 64 );
-        x  = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
+        dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( 
base64_dec_map ), *src );
+
+        mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( 
dec_map_lookup, 64 ) );
+        x  = ( x << 6 ) | ( dec_map_lookup & 0x3F );
 
         if( ++n == 4 )
         {
diff --git a/dll/3rdparty/mbedtls/bignum.c b/dll/3rdparty/mbedtls/bignum.c
index 3ed2a12173c..bc3491cdef1 100644
--- a/dll/3rdparty/mbedtls/bignum.c
+++ b/dll/3rdparty/mbedtls/bignum.c
@@ -1191,6 +1191,12 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const 
mbedtls_mpi *A, const mbedtls_mpi
     for( n = B->n; n > 0; n-- )
         if( B->p[n - 1] != 0 )
             break;
+    if( n > A->n )
+    {
+        /* B >= (2^ciL)^n > A */
+        ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
+        goto cleanup;
+    }
 
     carry = mpi_sub_hlp( n, X->p, B->p );
     if( carry != 0 )
diff --git a/dll/3rdparty/mbedtls/ctr_drbg.c b/dll/3rdparty/mbedtls/ctr_drbg.c
index bc5cc8f63f0..e275f1a7287 100644
--- a/dll/3rdparty/mbedtls/ctr_drbg.c
+++ b/dll/3rdparty/mbedtls/ctr_drbg.c
@@ -87,10 +87,6 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
     memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
 
     ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
-
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
 }
 
 /*
@@ -103,14 +99,13 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
         return;
 
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_free( &ctx->mutex );
+    /* The mutex is initialized iff f_entropy is set. */
+    if( ctx->f_entropy != NULL )
+        mbedtls_mutex_free( &ctx->mutex );
 #endif
     mbedtls_aes_free( &ctx->aes_ctx );
     mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
     ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
 }
 
 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context 
*ctx, int resistance )
@@ -382,6 +377,11 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
 
     memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
 
+    /* The mutex is initialized iff f_entropy is set. */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     mbedtls_aes_init( &ctx->aes_ctx );
 
     ctx->f_entropy = f_entropy;
diff --git a/dll/3rdparty/mbedtls/entropy.c b/dll/3rdparty/mbedtls/entropy.c
index ee98e4cdb94..fb5e0eca663 100644
--- a/dll/3rdparty/mbedtls/entropy.c
+++ b/dll/3rdparty/mbedtls/entropy.c
@@ -150,6 +150,11 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
 
 void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
 {
+    /* If the context was already free, don't call free() again.
+     * This is important for mutexes which don't allow double-free. */
+    if( ctx->accumulator_started == -1 )
+        return;
+
 #if defined(MBEDTLS_HAVEGE_C)
     mbedtls_havege_free( &ctx->havege_data );
 #endif
@@ -166,7 +171,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
 #endif
     ctx->source_count = 0;
     mbedtls_zeroize( ctx->source, sizeof( ctx->source ) );
-    ctx->accumulator_started = 0;
+    ctx->accumulator_started = -1;
 }
 
 int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
diff --git a/dll/3rdparty/mbedtls/hmac_drbg.c b/dll/3rdparty/mbedtls/hmac_drbg.c
index 26b15e95273..876fa574a84 100644
--- a/dll/3rdparty/mbedtls/hmac_drbg.c
+++ b/dll/3rdparty/mbedtls/hmac_drbg.c
@@ -88,10 +88,6 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
     memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
 
     ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
-
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
 }
 
 /*
@@ -161,6 +157,10 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context 
*ctx,
     if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     /*
      * Set initial working state.
      * Use the V memory location, which is currently all 0, to initialize the
@@ -286,6 +286,11 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
     if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
+    /* The mutex is initialized iff the md context is set up. */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     md_size = mbedtls_md_get_size( md_info );
 
     /*
@@ -453,14 +458,13 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context 
*ctx )
         return;
 
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_free( &ctx->mutex );
+    /* The mutex is initialized iff the md context is set up. */
+    if( ctx->md_ctx.md_info != NULL )
+        mbedtls_mutex_free( &ctx->mutex );
 #endif
     mbedtls_md_free( &ctx->md_ctx );
     mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
     ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
 }
 
 #if defined(MBEDTLS_FS_IO)
diff --git a/dll/3rdparty/mbedtls/net_sockets.c 
b/dll/3rdparty/mbedtls/net_sockets.c
index 2876f8fdd61..fa27603c131 100644
--- a/dll/3rdparty/mbedtls/net_sockets.c
+++ b/dll/3rdparty/mbedtls/net_sockets.c
@@ -535,6 +535,13 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char 
*buf, size_t len,
     if( fd < 0 )
         return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 
+    /* A limitation of select() is that it only works with file descriptors
+     * that are strictly less than FD_SETSIZE. This is a limitation of the
+     * fd_set type. Error out early, because attempting to call FD_SET on a
+     * large file descriptor is a buffer overflow on typical platforms. */
+    if( fd >= FD_SETSIZE )
+        return( MBEDTLS_ERR_NET_RECV_FAILED );
+
     FD_ZERO( &read_fds );
     FD_SET( fd, &read_fds );
 
diff --git a/dll/3rdparty/mbedtls/pkwrite.c b/dll/3rdparty/mbedtls/pkwrite.c
index b0295651904..d54c74a34eb 100644
--- a/dll/3rdparty/mbedtls/pkwrite.c
+++ b/dll/3rdparty/mbedtls/pkwrite.c
@@ -437,7 +437,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, 
unsigned char *buf, size_
  *      publicExponent    INTEGER   -- e            1 + 3 + MPI_MAX + 1
  *  }
  */
-#define RSA_PUB_DER_MAX_BYTES   38 + 2 * MBEDTLS_MPI_MAX_SIZE
+#define RSA_PUB_DER_MAX_BYTES   ( 38 + 2 * MBEDTLS_MPI_MAX_SIZE )
 
 /*
  * RSA private keys:
@@ -454,10 +454,10 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, 
unsigned char *buf, size_
  *      otherPrimeInfos   OtherPrimeInfos OPTIONAL  0 (not supported)
  *  }
  */
-#define MPI_MAX_SIZE_2          MBEDTLS_MPI_MAX_SIZE / 2 + \
-                                MBEDTLS_MPI_MAX_SIZE % 2
-#define RSA_PRV_DER_MAX_BYTES   47 + 3 * MBEDTLS_MPI_MAX_SIZE \
-                                   + 5 * MPI_MAX_SIZE_2
+#define MPI_MAX_SIZE_2          ( MBEDTLS_MPI_MAX_SIZE / 2 + \
+                                  MBEDTLS_MPI_MAX_SIZE % 2 )
+#define RSA_PRV_DER_MAX_BYTES   ( 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
+                                   + 5 * MPI_MAX_SIZE_2 )
 
 #else /* MBEDTLS_RSA_C */
 
@@ -478,7 +478,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, 
unsigned char *buf, size_
  *                                            + 2 * ECP_MAX (coords)    [1]
  *  }
  */
-#define ECP_PUB_DER_MAX_BYTES   30 + 2 * MBEDTLS_ECP_MAX_BYTES
+#define ECP_PUB_DER_MAX_BYTES   ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES )
 
 /*
  * EC private keys:
@@ -489,7 +489,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, 
unsigned char *buf, size_
  *      publicKey  [1] BIT STRING OPTIONAL      1 + 2 + [1] above
  *    }
  */
-#define ECP_PRV_DER_MAX_BYTES   29 + 3 * MBEDTLS_ECP_MAX_BYTES
+#define ECP_PRV_DER_MAX_BYTES   ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES )
 
 #else /* MBEDTLS_ECP_C */
 
@@ -498,10 +498,10 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, 
unsigned char *buf, size_
 
 #endif /* MBEDTLS_ECP_C */
 
-#define PUB_DER_MAX_BYTES   RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
-                            RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
-#define PRV_DER_MAX_BYTES   RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
-                            RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
+#define PUB_DER_MAX_BYTES   ( RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+                              RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES )
+#define PRV_DER_MAX_BYTES   ( RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
+                              RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES )
 
 int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, 
size_t size )
 {
diff --git a/dll/3rdparty/mbedtls/rsa.c b/dll/3rdparty/mbedtls/rsa.c
index 7e853b152cd..94ace5e2daf 100644
--- a/dll/3rdparty/mbedtls/rsa.c
+++ b/dll/3rdparty/mbedtls/rsa.c
@@ -499,6 +499,9 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
     mbedtls_rsa_set_padding( ctx, padding, hash_id );
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Set ctx->ver to nonzero to indicate that the mutex has been
+     * initialized and will need to be freed. */
+    ctx->ver = 1;
     mbedtls_mutex_init( &ctx->mutex );
 #endif
 }
@@ -535,15 +538,15 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
     int ret;
     mbedtls_mpi H, G;
 
-    if( f_rng == NULL || nbits < 128 || exponent < 3 )
-        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
-
-    if( nbits % 2 )
-        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
-
     mbedtls_mpi_init( &H );
     mbedtls_mpi_init( &G );
 
+    if( f_rng == NULL || nbits < 128 || exponent < 3 || nbits % 2 != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
     /*
      * find primes P and Q with Q < P so that:
      * GCD( E, (P-1)*(Q-1) ) == 1
@@ -607,7 +610,9 @@ cleanup:
     if( ret != 0 )
     {
         mbedtls_rsa_free( ctx );
-        return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
+        if( ( -ret & ~0x7f ) == 0 )
+            ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
+        return( ret );
     }
 
     return( 0 );
@@ -1040,10 +1045,10 @@ cleanup:
     mbedtls_mpi_free( &C );
     mbedtls_mpi_free( &I );
 
-    if( ret != 0 )
+    if( ret != 0 && ret >= -0x007f )
         return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
 
-    return( 0 );
+    return( ret );
 }
 
 #if defined(MBEDTLS_PKCS1_V21)
@@ -2325,7 +2330,6 @@ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const 
mbedtls_rsa_context *src )
 {
     int ret;
 
-    dst->ver = src->ver;
     dst->len = src->len;
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
@@ -2375,7 +2379,12 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
 #endif /* MBEDTLS_RSA_NO_CRT */
 
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_free( &ctx->mutex );
+    /* Free the mutex, but only if it hasn't been freed already. */
+    if( ctx->ver != 0 )
+    {
+        mbedtls_mutex_free( &ctx->mutex );
+        ctx->ver = 0;
+    }
 #endif
 }
 
diff --git a/dll/3rdparty/mbedtls/threading.c b/dll/3rdparty/mbedtls/threading.c
index 838cd74d93d..df16fe72f0c 100644
--- a/dll/3rdparty/mbedtls/threading.c
+++ b/dll/3rdparty/mbedtls/threading.c
@@ -60,6 +60,12 @@ static void threading_mutex_init_pthread( 
mbedtls_threading_mutex_t *mutex )
     if( mutex == NULL )
         return;
 
+    /* A nonzero value of is_valid indicates a successfully initialized
+     * mutex. This is a workaround for not being able to return an error
+     * code for this function. The lock/unlock functions return an error
+     * if is_valid is nonzero. The Mbed TLS unit test code uses this field
+     * to distinguish more states of the mutex; see helpers.function for
+     * details. */
     mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
 }
 
diff --git a/dll/3rdparty/mbedtls/version_features.c 
b/dll/3rdparty/mbedtls/version_features.c
index a3e3df4f998..ee13f7898a9 100644
--- a/dll/3rdparty/mbedtls/version_features.c
+++ b/dll/3rdparty/mbedtls/version_features.c
@@ -508,6 +508,9 @@ static const char *features[] = {
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
     "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
+#if defined(MBEDTLS_TEST_HOOKS)
+    "MBEDTLS_TEST_HOOKS",
+#endif /* MBEDTLS_TEST_HOOKS */
 #if defined(MBEDTLS_THREADING_ALT)
     "MBEDTLS_THREADING_ALT",
 #endif /* MBEDTLS_THREADING_ALT */
diff --git a/media/doc/3rd Party Files.txt b/media/doc/3rd Party Files.txt
index 9aa71f6de61..cb355cf0aa4 100644
--- a/media/doc/3rd Party Files.txt     
+++ b/media/doc/3rd Party Files.txt     
@@ -51,7 +51,7 @@ URL: http://xmlsoft.org
 
 Title: mbed TLS
 Path: dll/3rdparty/mbedtls
-Used Version: 2.7.18
+Used Version: 2.7.19
 License: Apache-2.0 (https://spdx.org/licenses/Apache-2.0.html)
 URL: https://tls.mbed.org/
 
diff --git a/sdk/include/reactos/libs/mbedtls/config.h 
b/sdk/include/reactos/libs/mbedtls/config.h
index cb716d2a7c3..6c6524c8661 100644
--- a/sdk/include/reactos/libs/mbedtls/config.h
+++ b/sdk/include/reactos/libs/mbedtls/config.h
@@ -1549,6 +1549,23 @@
  */
 //#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
 
+/**
+ * \def MBEDTLS_TEST_HOOKS
+ *
+ * Enable features for invasive testing such as introspection functions and
+ * hooks for fault injection. This enables additional unit tests.
+ *
+ * Merely enabling this feature should not change the behavior of the product.
+ * It only adds new code, and new branching points where the default behavior
+ * is the same as when this feature is disabled.
+ * However, this feature increases the attack surface: there is an added
+ * risk of vulnerabilities, and more gadgets that can make exploits easier.
+ * Therefore this feature must never be enabled in production.
+ *
+ * Uncomment to enable invasive tests.
+ */
+//#define MBEDTLS_TEST_HOOKS
+
 /**
  * \def MBEDTLS_THREADING_ALT
  *
diff --git a/sdk/include/reactos/libs/mbedtls/ctr_drbg.h 
b/sdk/include/reactos/libs/mbedtls/ctr_drbg.h
index 24d9870bee3..33fe63f482b 100644
--- a/sdk/include/reactos/libs/mbedtls/ctr_drbg.h
+++ b/sdk/include/reactos/libs/mbedtls/ctr_drbg.h
@@ -190,6 +190,13 @@ typedef struct
     void *p_entropy;            /*!< The context for the entropy function. */
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized if and only if f_entropy != NULL.
+     * This means that the mutex is initialized during the initial seeding
+     * in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free().
+     *
+     * Note that this invariant may change without notice. Do not rely on it
+     * and do not access the mutex directly in application code.
+     */
     mbedtls_threading_mutex_t mutex;
 #endif
 }
@@ -252,6 +259,15 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx 
);
  *                      device.
  */
 #endif
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
 /**
  * \param ctx           The CTR_DRBG context to seed.
  *                      It must have been initialized with
@@ -261,6 +277,8 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
  *                      the same context unless you call
  *                      mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
  *                      again first.
+ *                      After a failed call to mbedtls_ctr_drbg_seed(),
+ *                      you must call mbedtls_ctr_drbg_free().
  * \param f_entropy     The entropy callback, taking as arguments the
  *                      \p p_entropy context, the buffer to fill, and the
  *                      length of the buffer.
@@ -344,6 +362,11 @@ void mbedtls_ctr_drbg_set_reseed_interval( 
mbedtls_ctr_drbg_context *ctx,
  * \brief               This function reseeds the CTR_DRBG context, that is
  *                      extracts data from the entropy source.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The CTR_DRBG context.
  * \param additional    Additional data to add to the state. Can be \c NULL.
  * \param len           The length of the additional data.
@@ -361,6 +384,11 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
 /**
  * \brief               This function updates the state of the CTR_DRBG 
context.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The CTR_DRBG context.
  * \param additional    The data to update the state with. This must not be
  *                      \c NULL unless \p add_len is \c 0.
@@ -388,6 +416,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context 
*ctx,
  *                      #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
  *                      The remaining Bytes are silently discarded.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The CTR_DRBG context.
  * \param additional    The data to update the state with. This must not be
  *                      \c NULL unless \p add_len is \c 0.
@@ -405,6 +438,11 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context 
*ctx,
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
@@ -433,8 +471,16 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
  *
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
- *
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
diff --git a/sdk/include/reactos/libs/mbedtls/entropy.h 
b/sdk/include/reactos/libs/mbedtls/entropy.h
index cee6ab5a789..41648aaf20d 100644
--- a/sdk/include/reactos/libs/mbedtls/entropy.h
+++ b/sdk/include/reactos/libs/mbedtls/entropy.h
@@ -147,13 +147,15 @@ mbedtls_entropy_source_state;
  */
 typedef struct
 {
-    int accumulator_started;
+    int accumulator_started; /* 0 after init.
+                              * 1 after the first update.
+                              * -1 after free. */
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
     mbedtls_sha512_context  accumulator;
 #else
     mbedtls_sha256_context  accumulator;
 #endif
-    int             source_count;
+    int             source_count; /* Number of entries used in source. */
     mbedtls_entropy_source_state    source[MBEDTLS_ENTROPY_MAX_SOURCES];
 #if defined(MBEDTLS_HAVEGE_C)
     mbedtls_havege_state    havege_data;
diff --git a/sdk/include/reactos/libs/mbedtls/hmac_drbg.h 
b/sdk/include/reactos/libs/mbedtls/hmac_drbg.h
index cd23a16af62..4a797d4725e 100644
--- a/sdk/include/reactos/libs/mbedtls/hmac_drbg.h
+++ b/sdk/include/reactos/libs/mbedtls/hmac_drbg.h
@@ -128,6 +128,14 @@ typedef struct
     void *p_entropy;            /*!< context for the entropy function        */
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized if and only if
+     * md_ctx->md_info != NULL. This means that the mutex is initialized
+     * during the initial seeding in mbedtls_hmac_drbg_seed() or
+     * mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free().
+     *
+     * Note that this invariant may change without notice. Do not rely on it
+     * and do not access the mutex directly in application code.
+     */
     mbedtls_threading_mutex_t mutex;
 #endif
 } mbedtls_hmac_drbg_context;
@@ -177,7 +185,17 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context 
*ctx );
  * \note                During the initial seeding, this function calls
  *                      the entropy source to obtain a nonce
  *                      whose length is half the entropy length.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_hmac_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param ctx           HMAC_DRBG context to be seeded.
  * \param md_info       MD algorithm to use for HMAC_DRBG.
  * \param f_entropy     The entropy callback, taking as arguments the
@@ -216,7 +234,17 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
  *
  * This function is meant for use in algorithms that need a pseudorandom
  * input such as deterministic ECDSA.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_hmac_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param ctx           HMAC_DRBG context to be initialised.
  * \param md_info       MD algorithm to use for HMAC_DRBG.
  * \param data          Concatenation of the initial entropy string and
@@ -279,6 +307,11 @@ void mbedtls_hmac_drbg_set_reseed_interval( 
mbedtls_hmac_drbg_context *ctx,
 /**
  * \brief               This function updates the state of the HMAC_DRBG 
context.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The HMAC_DRBG context.
  * \param additional    The data to update the state with.
  *                      If this is \c NULL, there is no additional data.
@@ -297,6 +330,11 @@ int mbedtls_hmac_drbg_update_ret( 
mbedtls_hmac_drbg_context *ctx,
  * \warning             This function cannot report errors. You should use
  *                      mbedtls_hmac_drbg_update_ret() instead.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           HMAC_DRBG context
  * \param additional    Additional data to update state with, or NULL
  * \param add_len       Length of additional data, or 0
@@ -312,6 +350,11 @@ void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context 
*ctx,
  * \brief               This function reseeds the HMAC_DRBG context, that is
  *                      extracts data from the entropy source.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The HMAC_DRBG context.
  * \param additional    Additional data to add to the state.
  *                      If this is \c NULL, there is no additional data
@@ -337,6 +380,11 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context 
*ctx,
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
  *                      #mbedtls_hmac_drbg_context structure.
  * \param output        The buffer to fill.
@@ -366,7 +414,16 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
  *
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
  *                      #mbedtls_hmac_drbg_context structure.
  * \param output        The buffer to fill.
diff --git a/sdk/include/reactos/libs/mbedtls/net_sockets.h 
b/sdk/include/reactos/libs/mbedtls/net_sockets.h
index 0d61547d09f..5f2b1c5028a 100644
--- a/sdk/include/reactos/libs/mbedtls/net_sockets.h
+++ b/sdk/include/reactos/libs/mbedtls/net_sockets.h
@@ -130,6 +130,7 @@ int mbedtls_net_connect( mbedtls_net_context *ctx, const 
char *host, const char
  *
  * \return         0 if successful, or one of:
  *                      MBEDTLS_ERR_NET_SOCKET_FAILED,
+ *                      MBEDTLS_ERR_NET_UNKNOWN_HOST,
  *                      MBEDTLS_ERR_NET_BIND_FAILED,
  *                      MBEDTLS_ERR_NET_LISTEN_FAILED
  *
@@ -149,6 +150,8 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char 
*bind_ip, const char
  *                  can be NULL if client_ip is null
  *
  * \return          0 if successful, or
+ *                  MBEDTLS_ERR_NET_SOCKET_FAILED,
+ *                  MBEDTLS_ERR_NET_BIND_FAILED,
  *                  MBEDTLS_ERR_NET_ACCEPT_FAILED, or
  *                  MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
  *                  MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
@@ -219,16 +222,21 @@ int mbedtls_net_send( void *ctx, const unsigned char 
*buf, size_t len );
  *                 'timeout' seconds. If no error occurs, the actual amount
  *                 read is returned.
  *
+ * \note           The current implementation of this function uses
+ *                 select() and returns an error if the file descriptor
+ *                 is \c FD_SETSIZE or greater.
+ *
  * \param ctx      Socket
  * \param buf      The buffer to write to
  * \param len      Maximum length of the buffer
  * \param timeout  Maximum number of milliseconds to wait for data
  *                 0 means no timeout (wait forever)
  *
- * \return         the number of bytes received,
- *                 or a non-zero error code:
- *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ * \return         The number of bytes received if successful.
+ *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out.
  *                 MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
+ *                 Another negative error code (MBEDTLS_ERR_NET_xxx)
+ *                 for other failures.
  *
  * \note           This function will block (until data becomes available or
  *                 timeout is reached) even if the socket is set to
diff --git a/sdk/include/reactos/libs/mbedtls/rsa.h 
b/sdk/include/reactos/libs/mbedtls/rsa.h
index 7b508c5dcaa..cfb66dd8e61 100644
--- a/sdk/include/reactos/libs/mbedtls/rsa.h
+++ b/sdk/include/reactos/libs/mbedtls/rsa.h
@@ -118,7 +118,10 @@ extern "C" {
  */
 typedef struct
 {
-    int ver;                    /*!<  Always 0.*/
+    int ver;                    /*!<  Reserved for internal purposes.
+                                 *    Do not set this field in application
+                                 *    code. Its meaning might change without
+                                 *    notice. */
     size_t len;                 /*!<  The size of \p N in Bytes. */
 
     mbedtls_mpi N;                      /*!<  The public modulus. */
@@ -148,6 +151,7 @@ typedef struct
                                      mask generating function used in the
                                      EME-OAEP and EMSA-PSS encodings. */
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized iff ver != 0. */
     mbedtls_threading_mutex_t mutex;    /*!<  Thread-safety mutex. */
 #endif
 }
diff --git a/sdk/include/reactos/libs/mbedtls/threading.h 
b/sdk/include/reactos/libs/mbedtls/threading.h
index a5d0a34a66f..f1d53bdb10b 100644
--- a/sdk/include/reactos/libs/mbedtls/threading.h
+++ b/sdk/include/reactos/libs/mbedtls/threading.h
@@ -70,6 +70,9 @@ extern "C" {
 typedef struct
 {
     pthread_mutex_t mutex;
+    /* is_valid is 0 after a failed init or a free, and nonzero after a
+     * successful init. This field is not considered part of the public
+     * API of Mbed TLS and may change without notice. */
     char is_valid;
 } mbedtls_threading_mutex_t;
 #endif
diff --git a/sdk/include/reactos/libs/mbedtls/version.h 
b/sdk/include/reactos/libs/mbedtls/version.h
index 6775a4a955c..622bebf5ad9 100644
--- a/sdk/include/reactos/libs/mbedtls/version.h
+++ b/sdk/include/reactos/libs/mbedtls/version.h
@@ -65,16 +65,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  2
 #define MBEDTLS_VERSION_MINOR  7
-#define MBEDTLS_VERSION_PATCH  18
+#define MBEDTLS_VERSION_PATCH  19
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02071200
-#define MBEDTLS_VERSION_STRING         "2.7.18"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.7.18"
+#define MBEDTLS_VERSION_NUMBER         0x02071300
+#define MBEDTLS_VERSION_STRING         "2.7.19"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.7.19"
 
 #if defined(MBEDTLS_VERSION_C)
 

Reply via email to