From 1b00a1f50f10ad22e3625b479f3448ec99b71414 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sat, 4 Apr 2020 21:30:22 +0200 Subject: [PATCH] [MBEDTLS] Update to version 2.7.14. CORE-16787 --- dll/3rdparty/mbedtls/bignum.c | 5 +- dll/3rdparty/mbedtls/certs.c | 4 + dll/3rdparty/mbedtls/cipher.c | 14 +-- dll/3rdparty/mbedtls/pkparse.c | 122 +++++++++++++++------ dll/3rdparty/mbedtls/rsa.c | 8 +- dll/3rdparty/mbedtls/x509write_csr.c | 4 +- media/doc/3rd Party Files.txt | 2 +- sdk/include/reactos/libs/mbedtls/version.h | 8 +- 8 files changed, 115 insertions(+), 52 deletions(-) diff --git a/dll/3rdparty/mbedtls/bignum.c b/dll/3rdparty/mbedtls/bignum.c index 596e1a0164e..badc275c1de 100644 --- a/dll/3rdparty/mbedtls/bignum.c +++ b/dll/3rdparty/mbedtls/bignum.c @@ -153,9 +153,10 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) mbedtls_mpi_uint *p; size_t i; - /* Actually resize up in this case */ + /* Actually resize up if there are currently fewer than nblimbs limbs. */ if( X->n <= nblimbs ) return( mbedtls_mpi_grow( X, nblimbs ) ); + /* After this point, then X->n > nblimbs and in particular X->n > 0. */ for( i = X->n - 1; i > 0; i-- ) if( X->p[i] != 0 ) @@ -192,7 +193,7 @@ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ) if( X == Y ) return( 0 ); - if( Y->p == NULL ) + if( Y->n == 0 ) { mbedtls_mpi_free( X ); return( 0 ); diff --git a/dll/3rdparty/mbedtls/certs.c b/dll/3rdparty/mbedtls/certs.c index 78076f9f397..ae66bba6481 100644 --- a/dll/3rdparty/mbedtls/certs.c +++ b/dll/3rdparty/mbedtls/certs.c @@ -182,6 +182,10 @@ const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); #if defined(MBEDTLS_SHA256_C) /* tests/data_files/server2-sha256.crt */ +/* Or more precisely, this is the contents of the version of this file + * that's in the mbedtls-2.16 branch, due to a backporting mistake. + * We don't want to change the contents now, as that would change the size + * which is part of the ABI, which should be stable in LTS branches. */ #define TEST_SRV_CRT_RSA_SHA256 \ "-----BEGIN CERTIFICATE-----\r\n" \ "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ diff --git a/dll/3rdparty/mbedtls/cipher.c b/dll/3rdparty/mbedtls/cipher.c index dfb9cad7f49..ae71060687a 100644 --- a/dll/3rdparty/mbedtls/cipher.c +++ b/dll/3rdparty/mbedtls/cipher.c @@ -284,6 +284,10 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i *olen = 0; block_size = mbedtls_cipher_get_block_size( ctx ); + if ( 0 == block_size ) + { + return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); + } if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) { @@ -310,11 +314,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif - if ( 0 == block_size ) - { - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } - if( input == output && ( ctx->unprocessed_len != 0 || ilen % block_size ) ) { @@ -373,11 +372,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i */ if( 0 != ilen ) { - if( 0 == block_size ) - { - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } - /* Encryption: only cache partial blocks * Decryption w/ padding: always keep at least one whole block * Decryption w/o padding: only cache partial blocks diff --git a/dll/3rdparty/mbedtls/pkparse.c b/dll/3rdparty/mbedtls/pkparse.c index 8afe989f772..fd8f5157a95 100644 --- a/dll/3rdparty/mbedtls/pkparse.c +++ b/dll/3rdparty/mbedtls/pkparse.c @@ -665,6 +665,32 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, } #if defined(MBEDTLS_RSA_C) +/* + * Wrapper around mbedtls_asn1_get_mpi() that rejects zero. + * + * The value zero is: + * - never a valid value for an RSA parameter + * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete(). + * + * Since values can't be omitted in PKCS#1, passing a zero value to + * rsa_complete() would be incorrect, so reject zero values early. + */ +static int asn1_get_nonzero_mpi( unsigned char **p, + const unsigned char *end, + mbedtls_mpi *X ) +{ + int ret; + + ret = mbedtls_asn1_get_mpi( p, end, X ); + if( ret != 0 ) + return( ret ); + + if( mbedtls_mpi_cmp_int( X, 0 ) == 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); + + return( 0 ); +} + /* * Parse a PKCS#1 encoded private RSA key */ @@ -717,54 +743,84 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, } /* Import N */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0, - NULL, 0, NULL, 0 ) ) != 0 ) + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_rsa_import( rsa, &T, NULL, NULL, + NULL, NULL ) ) != 0 ) goto cleanup; - p += len; /* Import E */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, - NULL, 0, p, len ) ) != 0 ) + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL, + NULL, &T ) ) != 0 ) goto cleanup; - p += len; /* Import D */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, - p, len, NULL, 0 ) ) != 0 ) + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL, + &T, NULL ) ) != 0 ) goto cleanup; - p += len; /* Import P */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0, - NULL, 0, NULL, 0 ) ) != 0 ) + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_rsa_import( rsa, NULL, &T, NULL, + NULL, NULL ) ) != 0 ) goto cleanup; - p += len; /* Import Q */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len, - NULL, 0, NULL, 0 ) ) != 0 ) - goto cleanup; - p += len; - - /* Complete the RSA private key */ - if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 ) + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_rsa_import( rsa, NULL, NULL, &T, + NULL, NULL ) ) != 0 ) goto cleanup; - /* Check optional parameters */ - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ) +#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT) + /* + * The RSA CRT parameters DP, DQ and QP are nominally redundant, in + * that they can be easily recomputed from D, P and Q. However by + * parsing them from the PKCS1 structure it is possible to avoid + * recalculating them which both reduces the overhead of loading + * RSA private keys into memory and also avoids side channels which + * can arise when computing those values, since all of D, P, and Q + * are secret. See https://eprint.iacr.org/2020/055 for a + * description of one such attack. + */ + + /* Import DP */ + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_mpi_copy( &rsa->DP, &T ) ) != 0 ) + goto cleanup; + + /* Import DQ */ + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_mpi_copy( &rsa->DQ, &T ) ) != 0 ) + goto cleanup; + + /* Import QP */ + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_mpi_copy( &rsa->QP, &T ) ) != 0 ) + goto cleanup; + +#else + /* Verify existance of the CRT params */ + if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || + ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ) + goto cleanup; +#endif + + /* rsa_complete() doesn't complete anything with the default + * implementation but is still called: + * - for the benefit of alternative implementation that may want to + * pre-compute stuff beyond what's provided (eg Montgomery factors) + * - as is also sanity-checks the key + * + * Furthermore, we also check the public part for consistency with + * mbedtls_pk_parse_pubkey(), as it includes size minima for example. + */ + if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 || + ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 ) + { goto cleanup; + } if( p != end ) { diff --git a/dll/3rdparty/mbedtls/rsa.c b/dll/3rdparty/mbedtls/rsa.c index e9604e05d63..a014880bdd2 100644 --- a/dll/3rdparty/mbedtls/rsa.c +++ b/dll/3rdparty/mbedtls/rsa.c @@ -253,6 +253,12 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); +#if !defined(MBEDTLS_RSA_NO_CRT) + const int have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 ); + const int have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 ); + const int have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 ); +#endif + /* * Check whether provided parameters are enough * to deduce all others. The following incomplete @@ -318,7 +324,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) */ #if !defined(MBEDTLS_RSA_NO_CRT) - if( is_priv ) + if( is_priv && ! ( have_DP && have_DQ && have_QP ) ) { ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, &ctx->DP, &ctx->DQ, &ctx->QP ); diff --git a/dll/3rdparty/mbedtls/x509write_csr.c b/dll/3rdparty/mbedtls/x509write_csr.c index 3fd182b6a06..5d1114c5073 100644 --- a/dll/3rdparty/mbedtls/x509write_csr.c +++ b/dll/3rdparty/mbedtls/x509write_csr.c @@ -232,7 +232,9 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s /* * Prepare signature */ - mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); + ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); + if( ret != 0 ) + return( ret ); if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, f_rng, p_rng ) ) != 0 ) diff --git a/media/doc/3rd Party Files.txt b/media/doc/3rd Party Files.txt index c39445c5321..08e0455139c 100644 --- a/media/doc/3rd Party Files.txt +++ b/media/doc/3rd Party Files.txt @@ -84,7 +84,7 @@ Used Version: 4.1.0 Website: http://www.simplesystems.org/libtiff/ Title: mbed TLS -Used Version: 2.7.13 +Used Version: 2.7.14 Website: https://tls.mbed.org/ Title: libpng diff --git a/sdk/include/reactos/libs/mbedtls/version.h b/sdk/include/reactos/libs/mbedtls/version.h index 9f5fc45335b..6c93385b030 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 12 +#define MBEDTLS_VERSION_PATCH 14 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02070C00 -#define MBEDTLS_VERSION_STRING "2.7.12" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.7.12" +#define MBEDTLS_VERSION_NUMBER 0x02070E00 +#define MBEDTLS_VERSION_STRING "2.7.14" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.7.14" #if defined(MBEDTLS_VERSION_C)