summaryrefslogtreecommitdiff
path: root/thirdparty/mbedtls/library
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/mbedtls/library')
-rw-r--r--thirdparty/mbedtls/library/aes.c352
-rw-r--r--thirdparty/mbedtls/library/aesni.c35
-rw-r--r--thirdparty/mbedtls/library/arc4.c35
-rw-r--r--thirdparty/mbedtls/library/aria.c125
-rw-r--r--thirdparty/mbedtls/library/asn1parse.c243
-rw-r--r--thirdparty/mbedtls/library/asn1write.c166
-rw-r--r--thirdparty/mbedtls/library/base64.c123
-rw-r--r--thirdparty/mbedtls/library/bignum.c790
-rw-r--r--thirdparty/mbedtls/library/blowfish.c74
-rw-r--r--thirdparty/mbedtls/library/camellia.c96
-rw-r--r--thirdparty/mbedtls/library/ccm.c98
-rw-r--r--thirdparty/mbedtls/library/certs.c594
-rw-r--r--thirdparty/mbedtls/library/chacha20.c77
-rw-r--r--thirdparty/mbedtls/library/chachapoly.c71
-rw-r--r--thirdparty/mbedtls/library/check_crypto_config.h91
-rw-r--r--thirdparty/mbedtls/library/cipher.c625
-rw-r--r--thirdparty/mbedtls/library/cipher_wrap.c179
-rw-r--r--thirdparty/mbedtls/library/cmac.c94
-rw-r--r--thirdparty/mbedtls/library/common.h305
-rw-r--r--thirdparty/mbedtls/library/constant_time.c819
-rw-r--r--thirdparty/mbedtls/library/constant_time_internal.h329
-rw-r--r--thirdparty/mbedtls/library/constant_time_invasive.h51
-rw-r--r--thirdparty/mbedtls/library/ctr_drbg.c444
-rw-r--r--thirdparty/mbedtls/library/debug.c57
-rw-r--r--thirdparty/mbedtls/library/des.c112
-rw-r--r--thirdparty/mbedtls/library/dhm.c93
-rw-r--r--thirdparty/mbedtls/library/ecdh.c116
-rw-r--r--thirdparty/mbedtls/library/ecdsa.c80
-rw-r--r--thirdparty/mbedtls/library/ecjpake.c83
-rw-r--r--thirdparty/mbedtls/library/ecp.c1307
-rw-r--r--thirdparty/mbedtls/library/ecp_curves.c136
-rw-r--r--thirdparty/mbedtls/library/ecp_invasive.h81
-rw-r--r--thirdparty/mbedtls/library/entropy.c60
-rw-r--r--thirdparty/mbedtls/library/entropy_poll.c108
-rw-r--r--thirdparty/mbedtls/library/error.c1194
-rw-r--r--thirdparty/mbedtls/library/gcm.c256
-rw-r--r--thirdparty/mbedtls/library/havege.c73
-rw-r--r--thirdparty/mbedtls/library/hkdf.c44
-rw-r--r--thirdparty/mbedtls/library/hmac_drbg.c50
-rw-r--r--thirdparty/mbedtls/library/md.c532
-rw-r--r--thirdparty/mbedtls/library/md2.c42
-rw-r--r--thirdparty/mbedtls/library/md4.c109
-rw-r--r--thirdparty/mbedtls/library/md5.c109
-rw-r--r--thirdparty/mbedtls/library/md_wrap.c611
-rw-r--r--thirdparty/mbedtls/library/memory_buffer_alloc.c35
-rw-r--r--thirdparty/mbedtls/library/mps_common.h195
-rw-r--r--thirdparty/mbedtls/library/mps_error.h103
-rw-r--r--thirdparty/mbedtls/library/mps_reader.c564
-rw-r--r--thirdparty/mbedtls/library/mps_reader.h382
-rw-r--r--thirdparty/mbedtls/library/mps_trace.c127
-rw-r--r--thirdparty/mbedtls/library/mps_trace.h175
-rw-r--r--thirdparty/mbedtls/library/net_sockets.c76
-rw-r--r--thirdparty/mbedtls/library/nist_kw.c87
-rw-r--r--thirdparty/mbedtls/library/oid.c98
-rw-r--r--thirdparty/mbedtls/library/padlock.c39
-rw-r--r--thirdparty/mbedtls/library/pem.c50
-rw-r--r--thirdparty/mbedtls/library/pk.c146
-rw-r--r--thirdparty/mbedtls/library/pk_wrap.c407
-rw-r--r--thirdparty/mbedtls/library/pkcs11.c29
-rw-r--r--thirdparty/mbedtls/library/pkcs12.c62
-rw-r--r--thirdparty/mbedtls/library/pkcs5.c113
-rw-r--r--thirdparty/mbedtls/library/pkparse.c177
-rw-r--r--thirdparty/mbedtls/library/pkwrite.c132
-rw-r--r--thirdparty/mbedtls/library/platform.c111
-rw-r--r--thirdparty/mbedtls/library/platform_util.c35
-rw-r--r--thirdparty/mbedtls/library/poly1305.c94
-rw-r--r--thirdparty/mbedtls/library/ripemd160.c111
-rw-r--r--thirdparty/mbedtls/library/rsa.c438
-rw-r--r--thirdparty/mbedtls/library/rsa_internal.c35
-rw-r--r--thirdparty/mbedtls/library/sha1.c111
-rw-r--r--thirdparty/mbedtls/library/sha256.c89
-rw-r--r--thirdparty/mbedtls/library/sha512.c214
-rw-r--r--thirdparty/mbedtls/library/ssl_cache.c107
-rw-r--r--thirdparty/mbedtls/library/ssl_ciphersuites.c210
-rw-r--r--thirdparty/mbedtls/library/ssl_cli.c1169
-rw-r--r--thirdparty/mbedtls/library/ssl_cookie.c62
-rw-r--r--thirdparty/mbedtls/library/ssl_msg.c5922
-rw-r--r--thirdparty/mbedtls/library/ssl_srv.c949
-rw-r--r--thirdparty/mbedtls/library/ssl_ticket.c210
-rw-r--r--thirdparty/mbedtls/library/ssl_tls.c9240
-rw-r--r--thirdparty/mbedtls/library/ssl_tls13_keys.c349
-rw-r--r--thirdparty/mbedtls/library/ssl_tls13_keys.h274
-rw-r--r--thirdparty/mbedtls/library/threading.c39
-rw-r--r--thirdparty/mbedtls/library/timing.c37
-rw-r--r--thirdparty/mbedtls/library/version.c35
-rw-r--r--thirdparty/mbedtls/library/version_features.c132
-rw-r--r--thirdparty/mbedtls/library/x509.c198
-rw-r--r--thirdparty/mbedtls/library/x509_create.c46
-rw-r--r--thirdparty/mbedtls/library/x509_crl.c112
-rw-r--r--thirdparty/mbedtls/library/x509_crt.c1043
-rw-r--r--thirdparty/mbedtls/library/x509_csr.c62
-rw-r--r--thirdparty/mbedtls/library/x509write_crt.c108
-rw-r--r--thirdparty/mbedtls/library/x509write_csr.c126
-rw-r--r--thirdparty/mbedtls/library/xtea.c68
94 files changed, 21765 insertions, 14037 deletions
diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c
index af19a3849f..31824e75cf 100644
--- a/thirdparty/mbedtls/library/aes.c
+++ b/thirdparty/mbedtls/library/aes.c
@@ -2,13 +2,7 @@
* FIPS-197 compliant AES implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
@@ -50,11 +23,7 @@
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_AES_C)
@@ -63,6 +32,7 @@
#include "mbedtls/aes.h"
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_PADLOCK_C)
#include "mbedtls/padlock.h"
#endif
@@ -87,29 +57,6 @@
#define AES_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
#if defined(MBEDTLS_PADLOCK_C) && \
( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
static int aes_padlock_ace = -1;
@@ -439,7 +386,7 @@ static void aes_gen_tables( void )
{
pow[i] = x;
log[x] = i;
- x = ( x ^ XTIME( x ) ) & 0xFF;
+ x = MBEDTLS_BYTE_0( x ^ XTIME( x ) );
}
/*
@@ -448,7 +395,7 @@ static void aes_gen_tables( void )
for( i = 0, x = 1; i < 10; i++ )
{
RCON[i] = (uint32_t) x;
- x = XTIME( x ) & 0xFF;
+ x = MBEDTLS_BYTE_0( XTIME( x ) );
}
/*
@@ -461,10 +408,10 @@ static void aes_gen_tables( void )
{
x = pow[255 - log[i]];
- y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ y = x; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+ x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+ x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+ x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
x ^= y ^ 0x63;
FSb[i] = (unsigned char) x;
@@ -477,8 +424,8 @@ static void aes_gen_tables( void )
for( i = 0; i < 256; i++ )
{
x = FSb[i];
- y = XTIME( x ) & 0xFF;
- z = ( y ^ x ) & 0xFF;
+ y = MBEDTLS_BYTE_0( XTIME( x ) );
+ z = MBEDTLS_BYTE_0( y ^ x );
FT0[i] = ( (uint32_t) y ) ^
( (uint32_t) x << 8 ) ^
@@ -620,7 +567,7 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
for( i = 0; i < ( keybits >> 5 ); i++ )
{
- GET_UINT32_LE( RK[i], key, i << 2 );
+ RK[i] = MBEDTLS_GET_UINT32_LE( key, i << 2 );
}
switch( ctx->nr )
@@ -630,10 +577,10 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
for( i = 0; i < 10; i++, RK += 4 )
{
RK[4] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[3] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[3] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[3] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[3] ) ] << 24 );
RK[5] = RK[1] ^ RK[4];
RK[6] = RK[2] ^ RK[5];
@@ -646,10 +593,10 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
for( i = 0; i < 8; i++, RK += 6 )
{
RK[6] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[5] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[5] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[5] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[5] ) ] << 24 );
RK[7] = RK[1] ^ RK[6];
RK[8] = RK[2] ^ RK[7];
@@ -664,20 +611,20 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
for( i = 0; i < 7; i++, RK += 8 )
{
RK[8] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[7] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[7] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[7] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[7] ) ] << 24 );
RK[9] = RK[1] ^ RK[8];
RK[10] = RK[2] ^ RK[9];
RK[11] = RK[3] ^ RK[10];
RK[12] = RK[4] ^
- ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[11] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[11] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[11] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[11] ) ] << 24 );
RK[13] = RK[5] ^ RK[12];
RK[14] = RK[6] ^ RK[13];
@@ -743,10 +690,10 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
{
for( j = 0; j < 4; j++, SK++ )
{
- *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^
- AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^
- AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
- AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
+ *RK++ = AES_RT0( FSb[ MBEDTLS_BYTE_0( *SK ) ] ) ^
+ AES_RT1( FSb[ MBEDTLS_BYTE_1( *SK ) ] ) ^
+ AES_RT2( FSb[ MBEDTLS_BYTE_2( *SK ) ] ) ^
+ AES_RT3( FSb[ MBEDTLS_BYTE_3( *SK ) ] );
}
}
@@ -792,7 +739,7 @@ int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *key1, *key2;
unsigned int key1bits, key2bits;
@@ -817,7 +764,7 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *key1, *key2;
unsigned int key1bits, key2bits;
@@ -839,52 +786,52 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
-#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
- do \
- { \
- (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \
- AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \
- \
- (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \
- AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \
- \
- (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \
- AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \
- \
- (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \
- AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+ do \
+ { \
+ (X0) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
+ AES_FT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
+ AES_FT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
+ AES_FT3( MBEDTLS_BYTE_3( Y3 ) ); \
+ \
+ (X1) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
+ AES_FT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
+ AES_FT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
+ AES_FT3( MBEDTLS_BYTE_3( Y0 ) ); \
+ \
+ (X2) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
+ AES_FT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
+ AES_FT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
+ AES_FT3( MBEDTLS_BYTE_3( Y1 ) ); \
+ \
+ (X3) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
+ AES_FT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
+ AES_FT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
+ AES_FT3( MBEDTLS_BYTE_3( Y2 ) ); \
} while( 0 )
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
do \
{ \
- (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \
- AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \
+ (X0) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
+ AES_RT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
+ AES_RT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
+ AES_RT3( MBEDTLS_BYTE_3( Y1 ) ); \
\
- (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \
- AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \
+ (X1) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
+ AES_RT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
+ AES_RT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
+ AES_RT3( MBEDTLS_BYTE_3( Y2 ) ); \
\
- (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \
- AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \
+ (X2) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
+ AES_RT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
+ AES_RT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
+ AES_RT3( MBEDTLS_BYTE_3( Y3 ) ); \
\
- (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \
- AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \
+ (X3) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
+ AES_RT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
+ AES_RT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
+ AES_RT3( MBEDTLS_BYTE_3( Y0 ) ); \
} while( 0 )
/*
@@ -903,10 +850,10 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
uint32_t Y[4];
} t;
- GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++;
- GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++;
- GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++;
- GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
+ t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
+ t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
+ t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
+ t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
{
@@ -917,33 +864,33 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
t.X[0] = *RK++ ^ \
- ( (uint32_t) FSb[ ( t.Y[0] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
t.X[1] = *RK++ ^ \
- ( (uint32_t) FSb[ ( t.Y[1] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
t.X[2] = *RK++ ^ \
- ( (uint32_t) FSb[ ( t.Y[2] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
t.X[3] = *RK++ ^ \
- ( (uint32_t) FSb[ ( t.Y[3] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
- PUT_UINT32_LE( t.X[0], output, 0 );
- PUT_UINT32_LE( t.X[1], output, 4 );
- PUT_UINT32_LE( t.X[2], output, 8 );
- PUT_UINT32_LE( t.X[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
mbedtls_platform_zeroize( &t, sizeof( t ) );
@@ -956,7 +903,7 @@ void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] )
{
- mbedtls_internal_aes_encrypt( ctx, input, output );
+ MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_encrypt( ctx, input, output ) );
}
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
@@ -976,10 +923,10 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
uint32_t Y[4];
} t;
- GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++;
- GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++;
- GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++;
- GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
+ t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
+ t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
+ t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
+ t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
{
@@ -990,33 +937,33 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
t.X[0] = *RK++ ^ \
- ( (uint32_t) RSb[ ( t.Y[0] ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
t.X[1] = *RK++ ^ \
- ( (uint32_t) RSb[ ( t.Y[1] ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
t.X[2] = *RK++ ^ \
- ( (uint32_t) RSb[ ( t.Y[2] ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
t.X[3] = *RK++ ^ \
- ( (uint32_t) RSb[ ( t.Y[3] ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
- PUT_UINT32_LE( t.X[0], output, 0 );
- PUT_UINT32_LE( t.X[1], output, 4 );
- PUT_UINT32_LE( t.X[2], output, 8 );
- PUT_UINT32_LE( t.X[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
mbedtls_platform_zeroize( &t, sizeof( t ) );
@@ -1029,7 +976,7 @@ void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] )
{
- mbedtls_internal_aes_decrypt( ctx, input, output );
+ MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_decrypt( ctx, input, output ) );
}
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
@@ -1082,7 +1029,7 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
unsigned char *output )
{
int i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char temp[16];
AES_VALIDATE_RET( ctx != NULL );
@@ -1152,35 +1099,6 @@ exit:
#if defined(MBEDTLS_CIPHER_MODE_XTS)
-/* Endianess with 64 bits values */
-#ifndef GET_UINT64_LE
-#define GET_UINT64_LE(n,b,i) \
-{ \
- (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
- | ( (uint64_t) (b)[(i) + 6] << 48 ) \
- | ( (uint64_t) (b)[(i) + 5] << 40 ) \
- | ( (uint64_t) (b)[(i) + 4] << 32 ) \
- | ( (uint64_t) (b)[(i) + 3] << 24 ) \
- | ( (uint64_t) (b)[(i) + 2] << 16 ) \
- | ( (uint64_t) (b)[(i) + 1] << 8 ) \
- | ( (uint64_t) (b)[(i) ] ); \
-}
-#endif
-
-#ifndef PUT_UINT64_LE
-#define PUT_UINT64_LE(n,b,i) \
-{ \
- (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
- (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
- (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
- (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) ] = (unsigned char) ( (n) ); \
-}
-#endif
-
typedef unsigned char mbedtls_be128[16];
/*
@@ -1196,14 +1114,14 @@ static void mbedtls_gf128mul_x_ble( unsigned char r[16],
{
uint64_t a, b, ra, rb;
- GET_UINT64_LE( a, x, 0 );
- GET_UINT64_LE( b, x, 8 );
+ a = MBEDTLS_GET_UINT64_LE( x, 0 );
+ b = MBEDTLS_GET_UINT64_LE( x, 8 );
ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
rb = ( a >> 63 ) | ( b << 1 );
- PUT_UINT64_LE( ra, r, 0 );
- PUT_UINT64_LE( rb, r, 8 );
+ MBEDTLS_PUT_UINT64_LE( ra, r, 0 );
+ MBEDTLS_PUT_UINT64_LE( rb, r, 8 );
}
/*
@@ -1216,7 +1134,7 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t blocks = length / 16;
size_t leftover = length % 16;
unsigned char tweak[16];
@@ -1329,7 +1247,7 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
unsigned char *output )
{
int c;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
AES_VALIDATE_RET( ctx != NULL );
@@ -1397,7 +1315,7 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char c;
unsigned char ov[17];
@@ -1489,7 +1407,7 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
unsigned char *output )
{
int c, i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
AES_VALIDATE_RET( ctx != NULL );
@@ -1884,7 +1802,7 @@ int mbedtls_aes_self_test( int verbose )
mode = i & 1;
if( verbose != 0 )
- mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
+ mbedtls_printf( " AES-ECB-%3u (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( buf, 0, 16 );
@@ -1946,7 +1864,7 @@ int mbedtls_aes_self_test( int verbose )
mode = i & 1;
if( verbose != 0 )
- mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
+ mbedtls_printf( " AES-CBC-%3u (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( iv , 0, 16 );
@@ -2021,7 +1939,7 @@ int mbedtls_aes_self_test( int verbose )
mode = i & 1;
if( verbose != 0 )
- mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
+ mbedtls_printf( " AES-CFB128-%3u (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, aes_test_cfb128_iv, 16 );
@@ -2084,7 +2002,7 @@ int mbedtls_aes_self_test( int verbose )
mode = i & 1;
if( verbose != 0 )
- mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
+ mbedtls_printf( " AES-OFB-%3u (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, aes_test_ofb_iv, 16 );
diff --git a/thirdparty/mbedtls/library/aesni.c b/thirdparty/mbedtls/library/aesni.c
index 358d4ad860..996292ff6d 100644
--- a/thirdparty/mbedtls/library/aesni.c
+++ b/thirdparty/mbedtls/library/aesni.c
@@ -2,13 +2,7 @@
* AES-NI support functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -49,11 +22,7 @@
* [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_AESNI_C)
diff --git a/thirdparty/mbedtls/library/arc4.c b/thirdparty/mbedtls/library/arc4.c
index 6729bab002..b34dc5e754 100644
--- a/thirdparty/mbedtls/library/arc4.c
+++ b/thirdparty/mbedtls/library/arc4.c
@@ -2,13 +2,7 @@
* An implementation of the ARCFOUR algorithm
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ARCFOUR algorithm was publicly disclosed on 94/09.
@@ -49,11 +22,7 @@
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ARC4_C)
diff --git a/thirdparty/mbedtls/library/aria.c b/thirdparty/mbedtls/library/aria.c
index 50ccb91c70..bc05c4a319 100644
--- a/thirdparty/mbedtls/library/aria.c
+++ b/thirdparty/mbedtls/library/aria.c
@@ -2,13 +2,7 @@
* ARIA implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -50,11 +23,7 @@
* [2] https://tools.ietf.org/html/rfc5794
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ARIA_C)
@@ -87,29 +56,6 @@
MBEDTLS_INTERNAL_VALIDATE( cond )
/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE( n, b, i ) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE( n, b, i ) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
-/*
* modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
*
* This is submatrix P1 in [1] Appendix B.1
@@ -266,22 +212,22 @@ static inline void aria_sl( uint32_t *a, uint32_t *b,
const uint8_t sa[256], const uint8_t sb[256],
const uint8_t sc[256], const uint8_t sd[256] )
{
- *a = ( (uint32_t) sa[ *a & 0xFF] ) ^
- (((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^
- (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
- (((uint32_t) sd[ *a >> 24 ]) << 24);
- *b = ( (uint32_t) sa[ *b & 0xFF] ) ^
- (((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^
- (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
- (((uint32_t) sd[ *b >> 24 ]) << 24);
- *c = ( (uint32_t) sa[ *c & 0xFF] ) ^
- (((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^
- (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
- (((uint32_t) sd[ *c >> 24 ]) << 24);
- *d = ( (uint32_t) sa[ *d & 0xFF] ) ^
- (((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^
- (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
- (((uint32_t) sd[ *d >> 24 ]) << 24);
+ *a = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *a ) ] ) ^
+ (((uint32_t) sb[ MBEDTLS_BYTE_1( *a ) ]) << 8) ^
+ (((uint32_t) sc[ MBEDTLS_BYTE_2( *a ) ]) << 16) ^
+ (((uint32_t) sd[ MBEDTLS_BYTE_3( *a ) ]) << 24);
+ *b = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *b ) ] ) ^
+ (((uint32_t) sb[ MBEDTLS_BYTE_1( *b ) ]) << 8) ^
+ (((uint32_t) sc[ MBEDTLS_BYTE_2( *b ) ]) << 16) ^
+ (((uint32_t) sd[ MBEDTLS_BYTE_3( *b ) ]) << 24);
+ *c = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *c ) ] ) ^
+ (((uint32_t) sb[ MBEDTLS_BYTE_1( *c ) ]) << 8) ^
+ (((uint32_t) sc[ MBEDTLS_BYTE_2( *c ) ]) << 16) ^
+ (((uint32_t) sd[ MBEDTLS_BYTE_3( *c ) ]) << 24);
+ *d = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *d ) ] ) ^
+ (((uint32_t) sb[ MBEDTLS_BYTE_1( *d ) ]) << 8) ^
+ (((uint32_t) sc[ MBEDTLS_BYTE_2( *d ) ]) << 16) ^
+ (((uint32_t) sd[ MBEDTLS_BYTE_3( *d ) ]) << 24);
}
/*
@@ -439,7 +385,8 @@ static void aria_fe_xor( uint32_t r[4], const uint32_t p[4],
* Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
*
* We chose to store bytes into 32-bit words in little-endian format (see
- * GET/PUT_UINT32_LE) so we need to reverse bytes here.
+ * MBEDTLS_GET_UINT32_LE / MBEDTLS_PUT_UINT32_LE ) so we need to reverse
+ * bytes here.
*/
static void aria_rot128( uint32_t r[4], const uint32_t a[4],
const uint32_t b[4], uint8_t n )
@@ -487,21 +434,21 @@ int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
/* Copy key to W0 (and potential remainder to W1) */
- GET_UINT32_LE( w[0][0], key, 0 );
- GET_UINT32_LE( w[0][1], key, 4 );
- GET_UINT32_LE( w[0][2], key, 8 );
- GET_UINT32_LE( w[0][3], key, 12 );
+ w[0][0] = MBEDTLS_GET_UINT32_LE( key, 0 );
+ w[0][1] = MBEDTLS_GET_UINT32_LE( key, 4 );
+ w[0][2] = MBEDTLS_GET_UINT32_LE( key, 8 );
+ w[0][3] = MBEDTLS_GET_UINT32_LE( key, 12 );
memset( w[1], 0, 16 );
if( keybits >= 192 )
{
- GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key
- GET_UINT32_LE( w[1][1], key, 20 );
+ w[1][0] = MBEDTLS_GET_UINT32_LE( key, 16 ); // 192 bit key
+ w[1][1] = MBEDTLS_GET_UINT32_LE( key, 20 );
}
if( keybits == 256 )
{
- GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key
- GET_UINT32_LE( w[1][3], key, 28 );
+ w[1][2] = MBEDTLS_GET_UINT32_LE( key, 24 ); // 256 bit key
+ w[1][3] = MBEDTLS_GET_UINT32_LE( key, 28 );
}
i = ( keybits - 128 ) >> 6; // index: 0, 1, 2
@@ -578,10 +525,10 @@ int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
ARIA_VALIDATE_RET( input != NULL );
ARIA_VALIDATE_RET( output != NULL );
- GET_UINT32_LE( a, input, 0 );
- GET_UINT32_LE( b, input, 4 );
- GET_UINT32_LE( c, input, 8 );
- GET_UINT32_LE( d, input, 12 );
+ a = MBEDTLS_GET_UINT32_LE( input, 0 );
+ b = MBEDTLS_GET_UINT32_LE( input, 4 );
+ c = MBEDTLS_GET_UINT32_LE( input, 8 );
+ d = MBEDTLS_GET_UINT32_LE( input, 12 );
i = 0;
while( 1 )
@@ -613,10 +560,10 @@ int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
c ^= ctx->rk[i][2];
d ^= ctx->rk[i][3];
- PUT_UINT32_LE( a, output, 0 );
- PUT_UINT32_LE( b, output, 4 );
- PUT_UINT32_LE( c, output, 8 );
- PUT_UINT32_LE( d, output, 12 );
+ MBEDTLS_PUT_UINT32_LE( a, output, 0 );
+ MBEDTLS_PUT_UINT32_LE( b, output, 4 );
+ MBEDTLS_PUT_UINT32_LE( c, output, 8 );
+ MBEDTLS_PUT_UINT32_LE( d, output, 12 );
return( 0 );
}
diff --git a/thirdparty/mbedtls/library/asn1parse.c b/thirdparty/mbedtls/library/asn1parse.c
index 10239fdd15..22747d3ba4 100644
--- a/thirdparty/mbedtls/library/asn1parse.c
+++ b/thirdparty/mbedtls/library/asn1parse.c
@@ -2,13 +2,7 @@
* Generic ASN.1 parsing
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,39 +15,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "mbedtls/asn1.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -149,7 +119,7 @@ int mbedtls_asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
@@ -164,21 +134,41 @@ int mbedtls_asn1_get_bool( unsigned char **p,
return( 0 );
}
-int mbedtls_asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val )
+static int asn1_get_tagged_int( unsigned char **p,
+ const unsigned char *end,
+ int tag, int *val )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &len, tag ) ) != 0 )
return( ret );
- if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 )
+ /*
+ * len==0 is malformed (0 must be represented as 020100 for INTEGER,
+ * or 0A0100 for ENUMERATED tags
+ */
+ if( len == 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ /* This is a cryptography library. Reject negative integers. */
+ if( ( **p & 0x80 ) != 0 )
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- *val = 0;
+ /* Skip leading zeros. */
+ while( len > 0 && **p == 0 )
+ {
+ ++( *p );
+ --len;
+ }
+ /* Reject integers that don't fit in an int. This code assumes that
+ * the int type has no padding bit. */
+ if( len > sizeof( int ) )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ if( len == sizeof( int ) && ( **p & 0x80 ) != 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+ *val = 0;
while( len-- > 0 )
{
*val = ( *val << 8 ) | **p;
@@ -188,12 +178,26 @@ int mbedtls_asn1_get_int( unsigned char **p,
return( 0 );
}
+int mbedtls_asn1_get_int( unsigned char **p,
+ const unsigned char *end,
+ int *val )
+{
+ return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_INTEGER, val) );
+}
+
+int mbedtls_asn1_get_enum( unsigned char **p,
+ const unsigned char *end,
+ int *val )
+{
+ return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_ENUMERATED, val) );
+}
+
#if defined(MBEDTLS_BIGNUM_C)
int mbedtls_asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
@@ -210,7 +214,7 @@ int mbedtls_asn1_get_mpi( unsigned char **p,
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
mbedtls_asn1_bitstring *bs)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Certificate type is a single byte bitstring */
if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
@@ -238,82 +242,145 @@ int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
}
/*
- * Get a bit string without unused bits
+ * Traverse an ASN.1 "SEQUENCE OF <tag>"
+ * and call a callback for each entry found.
*/
-int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
- size_t *len )
-{
- int ret;
-
- if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
- return( ret );
-
- if( (*len)-- < 2 || *(*p)++ != 0 )
- return( MBEDTLS_ERR_ASN1_INVALID_DATA );
-
- return( 0 );
-}
-
-
-
-/*
- * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
- */
-int mbedtls_asn1_get_sequence_of( unsigned char **p,
- const unsigned char *end,
- mbedtls_asn1_sequence *cur,
- int tag)
+int mbedtls_asn1_traverse_sequence_of(
+ unsigned char **p,
+ const unsigned char *end,
+ unsigned char tag_must_mask, unsigned char tag_must_val,
+ unsigned char tag_may_mask, unsigned char tag_may_val,
+ int (*cb)( void *ctx, int tag,
+ unsigned char *start, size_t len ),
+ void *ctx )
{
int ret;
size_t len;
- mbedtls_asn1_buf *buf;
/* Get main sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ {
return( ret );
+ }
if( *p + len != end )
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
while( *p < end )
{
- buf = &(cur->buf);
- buf->tag = **p;
+ unsigned char const tag = *(*p)++;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
- return( ret );
+ if( ( tag & tag_must_mask ) != tag_must_val )
+ return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- buf->p = *p;
- *p += buf->len;
+ if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 )
+ return( ret );
- /* Allocate and assign next pointer */
- if( *p < end )
+ if( ( tag & tag_may_mask ) == tag_may_val )
{
- cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1,
- sizeof( mbedtls_asn1_sequence ) );
+ if( cb != NULL )
+ {
+ ret = cb( ctx, tag, *p, len );
+ if( ret != 0 )
+ return( ret );
+ }
+ }
- if( cur->next == NULL )
- return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+ *p += len;
+ }
- cur = cur->next;
- }
+ return( 0 );
+}
+
+/*
+ * Get a bit string without unused bits
+ */
+int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
+ size_t *len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
+ return( ret );
+
+ if( *len == 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+ --( *len );
+
+ if( **p != 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+ ++( *p );
+
+ return( 0 );
+}
+
+void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
+{
+ while( seq != NULL )
+ {
+ mbedtls_asn1_sequence *next = seq->next;
+ mbedtls_platform_zeroize( seq, sizeof( *seq ) );
+ mbedtls_free( seq );
+ seq = next;
}
+}
- /* Set final sequence entry's next pointer to NULL */
- cur->next = NULL;
+typedef struct
+{
+ int tag;
+ mbedtls_asn1_sequence *cur;
+} asn1_get_sequence_of_cb_ctx_t;
+
+static int asn1_get_sequence_of_cb( void *ctx,
+ int tag,
+ unsigned char *start,
+ size_t len )
+{
+ asn1_get_sequence_of_cb_ctx_t *cb_ctx =
+ (asn1_get_sequence_of_cb_ctx_t *) ctx;
+ mbedtls_asn1_sequence *cur =
+ cb_ctx->cur;
- if( *p != end )
- return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ if( cur->buf.p != NULL )
+ {
+ cur->next =
+ mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
+
+ if( cur->next == NULL )
+ return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+
+ cur = cur->next;
+ }
+ cur->buf.p = start;
+ cur->buf.len = len;
+ cur->buf.tag = tag;
+
+ cb_ctx->cur = cur;
return( 0 );
}
+/*
+ * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
+ */
+int mbedtls_asn1_get_sequence_of( unsigned char **p,
+ const unsigned char *end,
+ mbedtls_asn1_sequence *cur,
+ int tag)
+{
+ asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
+ memset( cur, 0, sizeof( mbedtls_asn1_sequence ) );
+ return( mbedtls_asn1_traverse_sequence_of(
+ p, end, 0xFF, tag, 0, 0,
+ asn1_get_sequence_of_cb, &cb_ctx ) );
+}
+
int mbedtls_asn1_get_alg( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
@@ -357,7 +424,7 @@ int mbedtls_asn1_get_alg_null( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_asn1_buf params;
memset( &params, 0, sizeof(mbedtls_asn1_buf) );
diff --git a/thirdparty/mbedtls/library/asn1write.c b/thirdparty/mbedtls/library/asn1write.c
index d94d0a7605..3811ef27a3 100644
--- a/thirdparty/mbedtls/library/asn1write.c
+++ b/thirdparty/mbedtls/library/asn1write.c
@@ -2,13 +2,7 @@
* ASN.1 buffer writing functionality
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,38 +15,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ASN1_WRITE_C)
#include "mbedtls/asn1write.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -90,8 +60,8 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
if( *p - start < 3 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = ( len ) & 0xFF;
- *--(*p) = ( len >> 8 ) & 0xFF;
+ *--(*p) = MBEDTLS_BYTE_0( len );
+ *--(*p) = MBEDTLS_BYTE_1( len );
*--(*p) = 0x82;
return( 3 );
}
@@ -101,9 +71,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
if( *p - start < 4 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = ( len ) & 0xFF;
- *--(*p) = ( len >> 8 ) & 0xFF;
- *--(*p) = ( len >> 16 ) & 0xFF;
+ *--(*p) = MBEDTLS_BYTE_0( len );
+ *--(*p) = MBEDTLS_BYTE_1( len );
+ *--(*p) = MBEDTLS_BYTE_2( len );
*--(*p) = 0x83;
return( 4 );
}
@@ -115,10 +85,10 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
if( *p - start < 5 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = ( len ) & 0xFF;
- *--(*p) = ( len >> 8 ) & 0xFF;
- *--(*p) = ( len >> 16 ) & 0xFF;
- *--(*p) = ( len >> 24 ) & 0xFF;
+ *--(*p) = MBEDTLS_BYTE_0( len );
+ *--(*p) = MBEDTLS_BYTE_1( len );
+ *--(*p) = MBEDTLS_BYTE_2( len );
+ *--(*p) = MBEDTLS_BYTE_3( len );
*--(*p) = 0x84;
return( 5 );
}
@@ -156,7 +126,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
#if defined(MBEDTLS_BIGNUM_C)
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
// Write the MPI
@@ -193,7 +163,7 @@ cleanup:
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
// Write NULL
@@ -207,7 +177,7 @@ int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
@@ -222,7 +192,7 @@ int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *s
const char *oid, size_t oid_len,
size_t par_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if( par_len == 0 )
@@ -241,7 +211,7 @@ int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *s
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if( *p - start < 1 )
@@ -256,36 +226,49 @@ int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolea
return( (int) len );
}
-int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
+static int asn1_write_tagged_int( unsigned char **p, unsigned char *start, int val, int tag )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
-
- len += 1;
- *--(*p) = val;
-
- if( val > 0 && **p & 0x80 )
+ do
{
if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+ len += 1;
+ *--(*p) = val & 0xff;
+ val >>= 8;
+ }
+ while( val > 0 );
+ if( **p & 0x80 )
+ {
+ if( *p - start < 1 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) );
return( (int) len );
}
+int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
+{
+ return( asn1_write_tagged_int( p, start, val, MBEDTLS_ASN1_INTEGER ) );
+}
+
+int mbedtls_asn1_write_enum( unsigned char **p, unsigned char *start, int val )
+{
+ return( asn1_write_tagged_int( p, start, val, MBEDTLS_ASN1_ENUMERATED ) );
+}
+
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag,
const char *text, size_t text_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
@@ -315,10 +298,53 @@ int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) );
}
+int mbedtls_asn1_write_named_bitstring( unsigned char **p,
+ unsigned char *start,
+ const unsigned char *buf,
+ size_t bits )
+{
+ size_t unused_bits, byte_len;
+ const unsigned char *cur_byte;
+ unsigned char cur_byte_shifted;
+ unsigned char bit;
+
+ byte_len = ( bits + 7 ) / 8;
+ unused_bits = ( byte_len * 8 ) - bits;
+
+ /*
+ * Named bitstrings require that trailing 0s are excluded in the encoding
+ * of the bitstring. Trailing 0s are considered part of the 'unused' bits
+ * when encoding this value in the first content octet
+ */
+ if( bits != 0 )
+ {
+ cur_byte = buf + byte_len - 1;
+ cur_byte_shifted = *cur_byte >> unused_bits;
+
+ for( ; ; )
+ {
+ bit = cur_byte_shifted & 0x1;
+ cur_byte_shifted >>= 1;
+
+ if( bit != 0 )
+ break;
+
+ bits--;
+ if( bits == 0 )
+ break;
+
+ if( bits % 8 == 0 )
+ cur_byte_shifted = *--cur_byte;
+ }
+ }
+
+ return( mbedtls_asn1_write_bitstring( p, start, buf, bits ) );
+}
+
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
size_t unused_bits, byte_len;
@@ -351,7 +377,7 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) );
@@ -411,18 +437,26 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
memcpy( cur->oid.p, oid, oid_len );
cur->val.len = val_len;
- cur->val.p = mbedtls_calloc( 1, val_len );
- if( cur->val.p == NULL )
+ if( val_len != 0 )
{
- mbedtls_free( cur->oid.p );
- mbedtls_free( cur );
- return( NULL );
+ cur->val.p = mbedtls_calloc( 1, val_len );
+ if( cur->val.p == NULL )
+ {
+ mbedtls_free( cur->oid.p );
+ mbedtls_free( cur );
+ return( NULL );
+ }
}
cur->next = *head;
*head = cur;
}
- else if( cur->val.len < val_len )
+ else if( val_len == 0 )
+ {
+ mbedtls_free( cur->val.p );
+ cur->val.p = NULL;
+ }
+ else if( cur->val.len != val_len )
{
/*
* Enlarge existing value buffer if needed
diff --git a/thirdparty/mbedtls/library/base64.c b/thirdparty/mbedtls/library/base64.c
index b1bd330ddd..83daa0bcc6 100644
--- a/thirdparty/mbedtls/library/base64.c
+++ b/thirdparty/mbedtls/library/base64.c
@@ -2,13 +2,7 @@
* RFC 1521 base64 encoding/decoding
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,38 +15,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
+#include "constant_time_internal.h"
#include <stdint.h>
@@ -68,38 +38,6 @@
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
-/* Return 0xff if low <= c <= high, 0 otherwise.
- *
- * Constant flow with respect to c.
- */
-static unsigned char mask_of_range( unsigned char low, unsigned char high,
- unsigned char c )
-{
- /* low_mask is: 0 if low <= c, 0x...ff if low > c */
- unsigned low_mask = ( (unsigned) c - low ) >> 8;
- /* high_mask is: 0 if c <= high, 0x...ff if c > high */
- unsigned high_mask = ( (unsigned) high - c ) >> 8;
- return( ~( low_mask | high_mask ) & 0xff );
-}
-
-/* Given a value in the range 0..63, return the corresponding Base64 digit.
- * The implementation assumes that letters are consecutive (e.g. ASCII
- * but not EBCDIC).
- */
-static unsigned char enc_char( unsigned char val )
-{
- unsigned char digit = 0;
- /* For each range of values, if val is in that range, mask digit with
- * the corresponding value. Since val can only be in a single range,
- * only at most one masking will change digit. */
- digit |= mask_of_range( 0, 25, val ) & ( 'A' + val );
- digit |= mask_of_range( 26, 51, val ) & ( 'a' + val - 26 );
- digit |= mask_of_range( 52, 61, val ) & ( '0' + val - 52 );
- digit |= mask_of_range( 62, 62, val ) & '+';
- digit |= mask_of_range( 63, 63, val ) & '/';
- return( digit );
-}
-
/*
* Encode a buffer into base64 format
*/
@@ -140,10 +78,12 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
C2 = *src++;
C3 = *src++;
- *p++ = enc_char( ( C1 >> 2 ) & 0x3F );
- *p++ = enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F );
- *p++ = enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F );
- *p++ = enc_char( C3 & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( C1 >> 2 ) & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) )
+ & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) )
+ & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( C3 & 0x3F );
}
if( i < slen )
@@ -151,11 +91,12 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
C1 = *src++;
C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
- *p++ = enc_char( ( C1 >> 2 ) & 0x3F );
- *p++ = enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( C1 >> 2 ) & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) )
+ & 0x3F );
if( ( i + 1 ) < slen )
- *p++ = enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F );
else *p++ = '=';
*p++ = '=';
@@ -167,34 +108,6 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
return( 0 );
}
-/* Given a Base64 digit, return its value.
- * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
- * return -1.
- *
- * The implementation assumes that letters are consecutive (e.g. ASCII
- * but not EBCDIC).
- *
- * The implementation is constant-flow (no branch or memory access depending
- * on the value of c) unless the compiler inlines and optimizes a specific
- * access.
- */
-static signed char dec_value( unsigned char c )
-{
- unsigned char val = 0;
- /* For each range of digits, if c is in that range, mask val with
- * the corresponding value. Since c can only be in a single range,
- * only at most one masking will change val. Set val to one plus
- * the desired value so that it stays 0 if c is in none of the ranges. */
- val |= mask_of_range( 'A', 'Z', c ) & ( c - 'A' + 0 + 1 );
- val |= mask_of_range( 'a', 'z', c ) & ( c - 'a' + 26 + 1 );
- val |= mask_of_range( '0', '9', c ) & ( c - '0' + 52 + 1 );
- val |= mask_of_range( '+', '+', c ) & ( c - '+' + 62 + 1 );
- val |= mask_of_range( '/', '/', c ) & ( c - '/' + 63 + 1 );
- /* At this point, val is 0 if c is an invalid digit and v+1 if c is
- * a digit with the value v. */
- return( val - 1 );
-}
-
/*
* Decode a base64-formatted buffer
*/
@@ -247,7 +160,7 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
{
if( equals != 0 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
- if( dec_value( src[i] ) < 0 )
+ if( mbedtls_ct_base64_dec_value( src[i] ) < 0 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
}
n++;
@@ -282,14 +195,14 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
if( *src == '=' )
++equals;
else
- x |= dec_value( *src );
+ x |= mbedtls_ct_base64_dec_value( *src );
if( ++accumulated_digits == 4 )
{
accumulated_digits = 0;
- *p++ = (unsigned char)( x >> 16 );
- if( equals <= 1 ) *p++ = (unsigned char)( x >> 8 );
- if( equals <= 0 ) *p++ = (unsigned char)( x );
+ *p++ = MBEDTLS_BYTE_2( x );
+ if( equals <= 1 ) *p++ = MBEDTLS_BYTE_1( x );
+ if( equals <= 0 ) *p++ = MBEDTLS_BYTE_0( x );
}
}
diff --git a/thirdparty/mbedtls/library/bignum.c b/thirdparty/mbedtls/library/bignum.c
index c553d0c5af..62e7f76727 100644
--- a/thirdparty/mbedtls/library/bignum.c
+++ b/thirdparty/mbedtls/library/bignum.c
@@ -2,13 +2,7 @@
* Multi-precision integer library
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -60,17 +33,15 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#include "mbedtls/bn_mul.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "constant_time_internal.h"
#include <limits.h>
#include <string.h>
@@ -212,8 +183,35 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
return( 0 );
}
+/* Resize X to have exactly n limbs and set it to 0. */
+static int mbedtls_mpi_resize_clear( mbedtls_mpi *X, size_t limbs )
+{
+ if( limbs == 0 )
+ {
+ mbedtls_mpi_free( X );
+ return( 0 );
+ }
+ else if( X->n == limbs )
+ {
+ memset( X->p, 0, limbs * ciL );
+ X->s = 1;
+ return( 0 );
+ }
+ else
+ {
+ mbedtls_mpi_free( X );
+ return( mbedtls_mpi_grow( X, limbs ) );
+ }
+}
+
/*
- * Copy the contents of Y into X
+ * Copy the contents of Y into X.
+ *
+ * This function is not constant-time. Leading zeros in Y may be removed.
+ *
+ * Ensure that X does not shrink. This is not guaranteed by the public API,
+ * but some code in the bignum module relies on this property, for example
+ * in mbedtls_mpi_exp_mod().
*/
int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
{
@@ -227,7 +225,11 @@ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
if( Y->n == 0 )
{
- mbedtls_mpi_free( X );
+ if( X->n != 0 )
+ {
+ X->s = 1;
+ memset( X->p, 0, X->n * ciL );
+ }
return( 0 );
}
@@ -268,168 +270,12 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
memcpy( Y, &T, sizeof( mbedtls_mpi ) );
}
-/**
- * Select between two sign values in constant-time.
- *
- * This is functionally equivalent to second ? a : b but uses only bit
- * operations in order to avoid branches.
- *
- * \param[in] a The first sign; must be either +1 or -1.
- * \param[in] b The second sign; must be either +1 or -1.
- * \param[in] second Must be either 1 (return b) or 0 (return a).
- *
- * \return The selected sign value.
- */
-static int mpi_safe_cond_select_sign( int a, int b, unsigned char second )
-{
- /* In order to avoid questions about what we can reasonnably assume about
- * the representations of signed integers, move everything to unsigned
- * by taking advantage of the fact that a and b are either +1 or -1. */
- unsigned ua = a + 1;
- unsigned ub = b + 1;
-
- /* second was 0 or 1, mask is 0 or 2 as are ua and ub */
- const unsigned mask = second << 1;
-
- /* select ua or ub */
- unsigned ur = ( ua & ~mask ) | ( ub & mask );
-
- /* ur is now 0 or 2, convert back to -1 or +1 */
- return( (int) ur - 1 );
-}
-
-/*
- * Conditionally assign dest = src, without leaking information
- * about whether the assignment was made or not.
- * dest and src must be arrays of limbs of size n.
- * assign must be 0 or 1.
- */
-static void mpi_safe_cond_assign( size_t n,
- mbedtls_mpi_uint *dest,
- const mbedtls_mpi_uint *src,
- unsigned char assign )
-{
- size_t i;
-
- /* 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
-
- /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
- const mbedtls_mpi_uint mask = -assign;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- for( i = 0; i < n; i++ )
- dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
-}
-
-/*
- * Conditionally assign X = Y, without leaking information
- * about whether the assignment was made or not.
- * (Leaking information about the respective sizes of X and Y is ok however.)
- */
-int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
-{
- int ret = 0;
- size_t i;
- mbedtls_mpi_uint limb_mask;
- MPI_VALIDATE_RET( X != NULL );
- MPI_VALIDATE_RET( Y != NULL );
-
- /* 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
-
- /* make sure assign is 0 or 1 in a time-constant manner */
- assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1);
- /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
- limb_mask = -assign;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
-
- X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign );
-
- mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
-
- for( i = Y->n; i < X->n; i++ )
- X->p[i] &= ~limb_mask;
-
-cleanup:
- return( ret );
-}
-
-/*
- * Conditionally swap X and Y, without leaking information
- * about whether the swap was made or not.
- * Here it is not ok to simply swap the pointers, which whould lead to
- * different memory access patterns when X and Y are used afterwards.
- */
-int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
-{
- int ret, s;
- size_t i;
- mbedtls_mpi_uint limb_mask;
- mbedtls_mpi_uint tmp;
- MPI_VALIDATE_RET( X != NULL );
- MPI_VALIDATE_RET( Y != NULL );
-
- if( X == Y )
- return( 0 );
-
- /* 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
-
- /* make sure swap is 0 or 1 in a time-constant manner */
- swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1);
- /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
- limb_mask = -swap;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
-
- s = X->s;
- X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
- Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
-
-
- for( i = 0; i < X->n; i++ )
- {
- tmp = X->p[i];
- X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
- Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
- }
-
-cleanup:
- return( ret );
-}
-
/*
* Set value from integer
*/
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MPI_VALIDATE_RET( X != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
@@ -572,7 +418,7 @@ static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
*/
int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, j, slen, n;
int sign = 1;
mbedtls_mpi_uint d;
@@ -585,6 +431,12 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
mbedtls_mpi_init( &T );
+ if( s[0] == 0 )
+ {
+ mbedtls_mpi_free( X );
+ return( 0 );
+ }
+
if( s[0] == '-' )
{
++s;
@@ -637,7 +489,7 @@ cleanup:
static int mpi_write_hlp( mbedtls_mpi *X, int radix,
char **p, const size_t buflen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi_uint r;
size_t length = 0;
char *p_end = *p + buflen;
@@ -802,7 +654,7 @@ int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
*/
int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n, slen, plen;
/*
* Buffer should have space for (short) label and decimal formatted MPI,
@@ -932,11 +784,37 @@ static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
}
/*
+ * Import X from unsigned binary data, little endian
+ */
+int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
+ const unsigned char *buf, size_t buflen )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t i;
+ size_t const limbs = CHARS_TO_LIMBS( buflen );
+
+ /* Ensure that target MPI has exactly the necessary number of limbs */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
+
+ for( i = 0; i < buflen; i++ )
+ X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
+
+cleanup:
+
+ /*
+ * This function is also used to import keys. However, wiping the buffers
+ * upon failure is not necessary because failure only can happen before any
+ * input is copied.
+ */
+ return( ret );
+}
+
+/*
* Import X from unsigned binary data, big endian
*/
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t const limbs = CHARS_TO_LIMBS( buflen );
size_t const overhead = ( limbs * ciL ) - buflen;
unsigned char *Xp;
@@ -945,17 +823,11 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu
MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
/* Ensure that target MPI has exactly the necessary number of limbs */
- if( X->n != limbs )
- {
- mbedtls_mpi_free( X );
- mbedtls_mpi_init( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
- /* Avoid calling `memcpy` with NULL source argument,
+ /* Avoid calling `memcpy` with NULL source or destination argument,
* even if buflen is 0. */
- if( buf != NULL )
+ if( buflen != 0 )
{
Xp = (unsigned char*) X->p;
memcpy( Xp + overhead, buf, buflen );
@@ -965,10 +837,54 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu
cleanup:
+ /*
+ * This function is also used to import keys. However, wiping the buffers
+ * upon failure is not necessary because failure only can happen before any
+ * input is copied.
+ */
return( ret );
}
/*
+ * Export X into unsigned binary data, little endian
+ */
+int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
+ unsigned char *buf, size_t buflen )
+{
+ size_t stored_bytes = X->n * ciL;
+ size_t bytes_to_copy;
+ size_t i;
+
+ if( stored_bytes < buflen )
+ {
+ bytes_to_copy = stored_bytes;
+ }
+ else
+ {
+ bytes_to_copy = buflen;
+
+ /* The output buffer is smaller than the allocated size of X.
+ * However X may fit if its leading bytes are zero. */
+ for( i = bytes_to_copy; i < stored_bytes; i++ )
+ {
+ if( GET_BYTE( X, i ) != 0 )
+ return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+ }
+ }
+
+ for( i = 0; i < bytes_to_copy; i++ )
+ buf[i] = GET_BYTE( X, i );
+
+ if( stored_bytes < buflen )
+ {
+ /* Write trailing 0 bytes */
+ memset( buf + stored_bytes, 0, buflen - stored_bytes );
+ }
+
+ return( 0 );
+}
+
+/*
* Export X into unsigned binary data, big endian
*/
int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
@@ -1019,7 +935,7 @@ int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
*/
int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, v0, t1;
mbedtls_mpi_uint r0 = 0, r1;
MPI_VALIDATE_RET( X != NULL );
@@ -1176,107 +1092,6 @@ int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
return( 0 );
}
-/** Decide if an integer is less than the other, without branches.
- *
- * \param x First integer.
- * \param y Second integer.
- *
- * \return 1 if \p x is less than \p y, 0 otherwise
- */
-static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
- const mbedtls_mpi_uint y )
-{
- mbedtls_mpi_uint ret;
- mbedtls_mpi_uint cond;
-
- /*
- * Check if the most significant bits (MSB) of the operands are different.
- */
- cond = ( x ^ y );
- /*
- * If the MSB are the same then the difference x-y will be negative (and
- * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
- */
- ret = ( x - y ) & ~cond;
- /*
- * If the MSB are different, then the operand with the MSB of 1 is the
- * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
- * the MSB of y is 0.)
- */
- ret |= y & cond;
-
-
- ret = ret >> ( biL - 1 );
-
- return (unsigned) ret;
-}
-
-/*
- * Compare signed values in constant time
- */
-int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
- unsigned *ret )
-{
- size_t i;
- /* The value of any of these variables is either 0 or 1 at all times. */
- unsigned cond, done, X_is_negative, Y_is_negative;
-
- MPI_VALIDATE_RET( X != NULL );
- MPI_VALIDATE_RET( Y != NULL );
- MPI_VALIDATE_RET( ret != NULL );
-
- if( X->n != Y->n )
- return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
-
- /*
- * Set sign_N to 1 if N >= 0, 0 if N < 0.
- * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
- */
- X_is_negative = ( X->s & 2 ) >> 1;
- Y_is_negative = ( Y->s & 2 ) >> 1;
-
- /*
- * If the signs are different, then the positive operand is the bigger.
- * That is if X is negative (X_is_negative == 1), then X < Y is true and it
- * is false if X is positive (X_is_negative == 0).
- */
- cond = ( X_is_negative ^ Y_is_negative );
- *ret = cond & X_is_negative;
-
- /*
- * This is a constant-time function. We might have the result, but we still
- * need to go through the loop. Record if we have the result already.
- */
- done = cond;
-
- for( i = X->n; i > 0; i-- )
- {
- /*
- * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
- * X and Y are negative.
- *
- * Again even if we can make a decision, we just mark the result and
- * the fact that we are done and continue looping.
- */
- cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
- *ret |= cond & ( 1 - done ) & X_is_negative;
- done |= cond;
-
- /*
- * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
- * X and Y are positive.
- *
- * Again even if we can make a decision, we just mark the result and
- * the fact that we are done and continue looping.
- */
- cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
- *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
- done |= cond;
- }
-
- return( 0 );
-}
-
/*
* Compare signed values
*/
@@ -1299,7 +1114,7 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
*/
int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, j;
mbedtls_mpi_uint *o, *p, c, tmp;
MPI_VALIDATE_RET( X != NULL );
@@ -1356,29 +1171,32 @@ cleanup:
/**
* Helper for mbedtls_mpi subtraction.
*
- * Calculate d - s where d and s have the same size.
+ * Calculate l - r where l and r have the same size.
* This function operates modulo (2^ciL)^n and returns the carry
- * (1 if there was a wraparound, i.e. if `d < s`, and 0 otherwise).
+ * (1 if there was a wraparound, i.e. if `l < r`, and 0 otherwise).
*
- * \param n Number of limbs of \p d and \p s.
- * \param[in,out] d On input, the left operand.
- * On output, the result of the subtraction:
- * \param[in] s The right operand.
+ * d may be aliased to l or r.
*
- * \return 1 if `d < s`.
- * 0 if `d >= s`.
+ * \param n Number of limbs of \p d, \p l and \p r.
+ * \param[out] d The result of the subtraction.
+ * \param[in] l The left operand.
+ * \param[in] r The right operand.
+ *
+ * \return 1 if `l < r`.
+ * 0 if `l >= r`.
*/
static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
mbedtls_mpi_uint *d,
- const mbedtls_mpi_uint *s )
+ const mbedtls_mpi_uint *l,
+ const mbedtls_mpi_uint *r )
{
size_t i;
- mbedtls_mpi_uint c, z;
+ mbedtls_mpi_uint c = 0, t, z;
- for( i = c = 0; i < n; i++, s++, d++ )
+ for( i = 0; i < n; i++ )
{
- z = ( *d < c ); *d -= c;
- c = ( *d < *s ) + z; *d -= *s;
+ z = ( l[i] < c ); t = l[i] - c;
+ c = ( t < r[i] ) + z; d[i] = t - r[i];
}
return( c );
@@ -1389,32 +1207,13 @@ static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
*/
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- mbedtls_mpi TB;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
mbedtls_mpi_uint carry;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
- mbedtls_mpi_init( &TB );
-
- if( X == B )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
- B = &TB;
- }
-
- if( X != A )
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
-
- /*
- * X should always be positive as a result of unsigned subtractions.
- */
- X->s = 1;
-
- ret = 0;
-
for( n = B->n; n > 0; n-- )
if( B->p[n - 1] != 0 )
break;
@@ -1425,7 +1224,17 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
goto cleanup;
}
- carry = mpi_sub_hlp( n, X->p, B->p );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, A->n ) );
+
+ /* Set the high limbs of X to match A. Don't touch the lower limbs
+ * because X might be aliased to B, and we must not overwrite the
+ * significant digits of B. */
+ if( A->n > n )
+ memcpy( X->p + n, A->p + n, ( A->n - n ) * ciL );
+ if( X->n > A->n )
+ memset( X->p + A->n, 0, ( X->n - A->n ) * ciL );
+
+ carry = mpi_sub_hlp( n, X->p, A->p, B->p );
if( carry != 0 )
{
/* Propagate the carry to the first nonzero limb of X. */
@@ -1441,10 +1250,10 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
--X->p[n];
}
-cleanup:
-
- mbedtls_mpi_free( &TB );
+ /* X should always be positive as a result of unsigned subtractions. */
+ X->s = 1;
+cleanup:
return( ret );
}
@@ -1554,8 +1363,21 @@ int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
return( mbedtls_mpi_sub_mpi( X, A, &B ) );
}
-/*
- * Helper for mbedtls_mpi multiplication
+/** Helper for mbedtls_mpi multiplication.
+ *
+ * Add \p b * \p s to \p d.
+ *
+ * \param i The number of limbs of \p s.
+ * \param[in] s A bignum to multiply, of size \p i.
+ * It may overlap with \p d, but only if
+ * \p d <= \p s.
+ * Its leading limb must not be \c 0.
+ * \param[in,out] d The bignum to add to.
+ * It must be sufficiently large to store the
+ * result of the multiplication. This means
+ * \p i + 1 limbs if \p d[\p i - 1] started as 0 and \p b
+ * is not known a priori.
+ * \param b A scalar to multiply.
*/
static
#if defined(__APPLE__) && defined(__arm__)
@@ -1565,7 +1387,10 @@ static
*/
__attribute__ ((noinline))
#endif
-void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
+void mpi_mul_hlp( size_t i,
+ const mbedtls_mpi_uint *s,
+ mbedtls_mpi_uint *d,
+ mbedtls_mpi_uint b )
{
mbedtls_mpi_uint c = 0, t = 0;
@@ -1620,10 +1445,10 @@ void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mp
t++;
- do {
+ while( c != 0 )
+ {
*d += c; c = ( *d < c ); d++;
}
- while( c != 0 );
}
/*
@@ -1631,7 +1456,7 @@ void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mp
*/
int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, j;
mbedtls_mpi TA, TB;
int result_is_zero = 0;
@@ -1683,17 +1508,37 @@ cleanup:
*/
int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
{
- mbedtls_mpi B;
- mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
- B.s = 1;
- B.n = 1;
- B.p = p;
- p[0] = b;
+ /* mpi_mul_hlp can't deal with a leading 0. */
+ size_t n = A->n;
+ while( n > 0 && A->p[n - 1] == 0 )
+ --n;
+
+ /* The general method below doesn't work if n==0 or b==0. By chance
+ * calculating the result is trivial in those cases. */
+ if( b == 0 || n == 0 )
+ {
+ return( mbedtls_mpi_lset( X, 0 ) );
+ }
- return( mbedtls_mpi_mul_mpi( X, A, &B ) );
+ /* Calculate A*b as A + A*(b-1) to take advantage of mpi_mul_hlp */
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* In general, A * b requires 1 limb more than b. If
+ * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same
+ * number of limbs as A and the call to grow() is not required since
+ * copy() will take care of the growth if needed. However, experimentally,
+ * making the call to grow() unconditional causes slightly fewer
+ * calls to calloc() in ECP code, presumably because it reuses the
+ * same mpi for a while and this way the mpi is more likely to directly
+ * grow to its final size. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n + 1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
+ mpi_mul_hlp( n, A->p, X->p, b - 1 );
+
+cleanup:
+ return( ret );
}
/*
@@ -1798,9 +1643,10 @@ static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n, t, k;
mbedtls_mpi X, Y, Z, T1, T2;
+ mbedtls_mpi_uint TP2[3];
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
@@ -1808,7 +1654,17 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
- mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
+ mbedtls_mpi_init( &T1 );
+ /*
+ * Avoid dynamic memory allocations for constant-size T2.
+ *
+ * T2 is used for comparison only and the 3 limbs are assigned explicitly,
+ * so nobody increase the size of the MPI and we're safe to use an on-stack
+ * buffer.
+ */
+ T2.s = 1;
+ T2.n = sizeof( TP2 ) / sizeof( *TP2 );
+ T2.p = TP2;
if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
{
@@ -1823,8 +1679,7 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, A->n + 2 ) );
k = mbedtls_mpi_bitlen( &Y ) % biL;
if( k < biL - 1 )
@@ -1856,6 +1711,10 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
Y.p[t], NULL);
}
+ T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
+ T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
+ T2.p[2] = X.p[i];
+
Z.p[i - t - 1]++;
do
{
@@ -1865,11 +1724,6 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
T1.p[1] = Y.p[t];
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) );
- T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
- T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
- T2.p[2] = X.p[i];
}
while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
@@ -1905,7 +1759,8 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
cleanup:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
- mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
+ mbedtls_mpi_free( &T1 );
+ mbedtls_platform_zeroize( TP2, sizeof( TP2 ) );
return( ret );
}
@@ -1934,7 +1789,7 @@ int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
*/
int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MPI_VALIDATE_RET( R != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
@@ -2090,14 +1945,14 @@ static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi
* do the calculation without using conditional tests. */
/* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */
d[n] += 1;
- d[n] -= mpi_sub_hlp( n, d, N->p );
+ d[n] -= mpi_sub_hlp( n, d, d, N->p );
/* If d0 < N then d < (2^biL)^n
* so d[n] == 0 and we want to keep A as it is.
* If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n
* so d[n] == 1 and we want to set A to the result of the subtraction
* which is d - (2^biL)^n, i.e. the n least significant limbs of d.
* This exactly corresponds to a conditional assignment. */
- mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] );
+ mbedtls_ct_mpi_uint_cond_assign( n, A->p, d, (unsigned char) d[n] );
}
/*
@@ -2117,42 +1972,6 @@ static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
mpi_montmul( A, &U, N, mm, T );
}
-/*
- * Constant-flow boolean "equal" comparison:
- * return x == y
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations - it can be used in conjunction with
- * mbedtls_ssl_cf_mask_from_bit().
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
-{
- /* diff = 0 if x == y, non-zero otherwise */
- const size_t diff = x ^ y;
-
- /* 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
-
- /* diff_msb's most significant bit is equal to x != y */
- const size_t diff_msb = ( diff | (size_t) -diff );
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- /* diff1 = (x != y) ? 1 : 0 */
- const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
-
- return( 1 ^ diff1 );
-}
-
/**
* Select an MPI from a table without leaking the index.
*
@@ -2170,13 +1989,12 @@ static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
*/
static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx )
{
- int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
- size_t i;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- for( i = 0; i < T_size; i++ )
+ for( size_t i = 0; i < T_size; i++ )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
- (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
+ (unsigned char) mbedtls_ct_size_bool_eq( i, idx ) ) );
}
cleanup:
@@ -2190,7 +2008,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t wbits, wsize, one = 1;
size_t i, j, nblimbs;
size_t bufsize, nbits;
@@ -2272,14 +2090,18 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
* W[1] = A * R^2 * R^-1 mod N = A * R mod N
*/
if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
+ {
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
+ /* This should be a no-op because W[1] is already that large before
+ * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
+ * in mpi_montmul() below, so let's make sure. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n + 1 ) );
+ }
else
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
- /* Re-grow W[1] if necessary. This should be only necessary in one corner
- * case: when A == 0 represented with A.n == 0, mbedtls_mpi_copy shrinks
- * W[1] to 0 limbs. */
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n +1 ) );
+ /* Note that this is safe because W[1] always has at least N->n limbs
+ * (it grew above and was preserved by mbedtls_mpi_copy()). */
mpi_montmul( &W[1], &RR, N, mm, &T );
/*
@@ -2421,15 +2243,15 @@ cleanup:
*/
int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t lz, lzt;
- mbedtls_mpi TG, TA, TB;
+ mbedtls_mpi TA, TB;
MPI_VALIDATE_RET( G != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
- mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
+ mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
@@ -2450,9 +2272,6 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
if( lzt < lz )
lz = lzt;
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
-
TA.s = TB.s = 1;
/* We mostly follow the procedure described in HAC 14.54, but with some
@@ -2476,7 +2295,7 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
* Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
* and gcd(A',B') is odd or 0.
*
- * At the beginning, we have TA = |A|/2^a and TB = |B|/2^b.
+ * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
* The code maintains the following invariant:
* gcd(A,B) = 2^k * gcd(TA,TB) for some k (I)
*/
@@ -2528,8 +2347,35 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
cleanup:
- mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
+ mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
+
+ return( ret );
+}
+
+/* Fill X with n_bytes random bytes.
+ * X must already have room for those bytes.
+ * The ordering of the bytes returned from the RNG is suitable for
+ * deterministic ECDSA (see RFC 6979 §3.3 and mbedtls_mpi_random()).
+ * The size and sign of X are unchanged.
+ * n_bytes must not be 0.
+ */
+static int mpi_fill_random_internal(
+ mbedtls_mpi *X, size_t n_bytes,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const size_t limbs = CHARS_TO_LIMBS( n_bytes );
+ const size_t overhead = ( limbs * ciL ) - n_bytes;
+
+ if( X->n < limbs )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+ memset( X->p, 0, overhead );
+ memset( (unsigned char *) X->p + limbs * ciL, 0, ( X->n - limbs ) * ciL );
+ MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X->p + overhead, n_bytes ) );
+ mpi_bigendian_to_host( X->p, limbs );
+cleanup:
return( ret );
}
@@ -2544,29 +2390,95 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t const limbs = CHARS_TO_LIMBS( size );
- size_t const overhead = ( limbs * ciL ) - size;
- unsigned char *Xp;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( f_rng != NULL );
/* Ensure that target MPI has exactly the necessary number of limbs */
- if( X->n != limbs )
+ MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
+ if( size == 0 )
+ return( 0 );
+
+ ret = mpi_fill_random_internal( X, size, f_rng, p_rng );
+
+cleanup:
+ return( ret );
+}
+
+int mbedtls_mpi_random( mbedtls_mpi *X,
+ mbedtls_mpi_sint min,
+ const mbedtls_mpi *N,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ int count;
+ unsigned lt_lower = 1, lt_upper = 0;
+ size_t n_bits = mbedtls_mpi_bitlen( N );
+ size_t n_bytes = ( n_bits + 7 ) / 8;
+ mbedtls_mpi lower_bound;
+
+ if( min < 0 )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ if( mbedtls_mpi_cmp_int( N, min ) <= 0 )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+ /*
+ * When min == 0, each try has at worst a probability 1/2 of failing
+ * (the msb has a probability 1/2 of being 0, and then the result will
+ * be < N), so after 30 tries failure probability is a most 2**(-30).
+ *
+ * When N is just below a power of 2, as is the case when generating
+ * a random scalar on most elliptic curves, 1 try is enough with
+ * overwhelming probability. When N is just above a power of 2,
+ * as when generating a random scalar on secp224k1, each try has
+ * a probability of failing that is almost 1/2.
+ *
+ * The probabilities are almost the same if min is nonzero but negligible
+ * compared to N. This is always the case when N is crypto-sized, but
+ * it's convenient to support small N for testing purposes. When N
+ * is small, use a higher repeat count, otherwise the probability of
+ * failure is macroscopic.
+ */
+ count = ( n_bytes > 4 ? 30 : 250 );
+
+ mbedtls_mpi_init( &lower_bound );
+
+ /* Ensure that target MPI has exactly the same number of limbs
+ * as the upper bound, even if the upper bound has leading zeros.
+ * This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
+
+ /*
+ * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
+ * when f_rng is a suitably parametrized instance of HMAC_DRBG:
+ * - use the same byte ordering;
+ * - keep the leftmost n_bits bits of the generated octet string;
+ * - try until result is in the desired range.
+ * This also avoids any bias, which is especially important for ECDSA.
+ */
+ do
{
- mbedtls_mpi_free( X );
- mbedtls_mpi_init( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+ MBEDTLS_MPI_CHK( mpi_fill_random_internal( X, n_bytes, f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, 8 * n_bytes - n_bits ) );
- Xp = (unsigned char*) X->p;
- MBEDTLS_MPI_CHK( f_rng( p_rng, Xp + overhead, size ) );
+ if( --count == 0 )
+ {
+ ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+ goto cleanup;
+ }
- mpi_bigendian_to_host( X->p, limbs );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, &lt_lower ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &lt_upper ) );
+ }
+ while( lt_lower != 0 || lt_upper == 0 );
cleanup:
+ mbedtls_mpi_free( &lower_bound );
return( ret );
}
@@ -2575,7 +2487,7 @@ cleanup:
*/
int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
@@ -2828,7 +2740,7 @@ int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi XX;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( f_rng != NULL );
@@ -3165,7 +3077,7 @@ int mbedtls_mpi_self_test( int verbose )
cleanup:
if( ret != 0 && verbose != 0 )
- mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
+ mbedtls_printf( "Unexpected error, return code = %08X\n", (unsigned int) ret );
mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
diff --git a/thirdparty/mbedtls/library/blowfish.c b/thirdparty/mbedtls/library/blowfish.c
index a3f9be959f..621e9f76cd 100644
--- a/thirdparty/mbedtls/library/blowfish.c
+++ b/thirdparty/mbedtls/library/blowfish.c
@@ -2,13 +2,7 @@
* Blowfish implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The Blowfish block cipher was designed by Bruce Schneier in 1993.
@@ -50,11 +23,7 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_BLOWFISH_C)
@@ -71,29 +40,6 @@
#define BLOWFISH_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = {
0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
@@ -110,13 +56,13 @@ static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x )
unsigned short a, b, c, d;
uint32_t y;
- d = (unsigned short)(x & 0xFF);
+ d = MBEDTLS_BYTE_0( x );
x >>= 8;
- c = (unsigned short)(x & 0xFF);
+ c = MBEDTLS_BYTE_0( x );
x >>= 8;
- b = (unsigned short)(x & 0xFF);
+ b = MBEDTLS_BYTE_0( x );
x >>= 8;
- a = (unsigned short)(x & 0xFF);
+ a = MBEDTLS_BYTE_0( x );
y = ctx->S[0][a] + ctx->S[1][b];
y = y ^ ctx->S[2][c];
y = y + ctx->S[3][d];
@@ -273,8 +219,8 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
BLOWFISH_VALIDATE_RET( input != NULL );
BLOWFISH_VALIDATE_RET( output != NULL );
- GET_UINT32_BE( X0, input, 0 );
- GET_UINT32_BE( X1, input, 4 );
+ X0 = MBEDTLS_GET_UINT32_BE( input, 0 );
+ X1 = MBEDTLS_GET_UINT32_BE( input, 4 );
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
{
@@ -285,8 +231,8 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
blowfish_enc( ctx, &X0, &X1 );
}
- PUT_UINT32_BE( X0, output, 0 );
- PUT_UINT32_BE( X1, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( X0, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( X1, output, 4 );
return( 0 );
}
diff --git a/thirdparty/mbedtls/library/camellia.c b/thirdparty/mbedtls/library/camellia.c
index 6cf265e578..29d730ab53 100644
--- a/thirdparty/mbedtls/library/camellia.c
+++ b/thirdparty/mbedtls/library/camellia.c
@@ -2,13 +2,7 @@
* Camellia implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The Camellia block cipher was designed by NTT and Mitsubishi Electric
@@ -50,11 +23,7 @@
* http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CAMELLIA_C)
@@ -80,29 +49,6 @@
#define CAMELLIA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
static const unsigned char SIGMA_CHARS[6][8] =
{
{ 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
@@ -332,14 +278,14 @@ static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
I0 = x[0] ^ k[0];
I1 = x[1] ^ k[1];
- I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) |
- ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) |
- ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) |
- ((uint32_t) SBOX4((I0 ) & 0xFF) );
- I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) |
- ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) |
- ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) |
- ((uint32_t) SBOX1((I1 ) & 0xFF) );
+ I0 = ((uint32_t) SBOX1( MBEDTLS_BYTE_3( I0 )) << 24) |
+ ((uint32_t) SBOX2( MBEDTLS_BYTE_2( I0 )) << 16) |
+ ((uint32_t) SBOX3( MBEDTLS_BYTE_1( I0 )) << 8) |
+ ((uint32_t) SBOX4( MBEDTLS_BYTE_0( I0 )) );
+ I1 = ((uint32_t) SBOX2( MBEDTLS_BYTE_3( I1 )) << 24) |
+ ((uint32_t) SBOX3( MBEDTLS_BYTE_2( I1 )) << 16) |
+ ((uint32_t) SBOX4( MBEDTLS_BYTE_1( I1 )) << 8) |
+ ((uint32_t) SBOX1( MBEDTLS_BYTE_0( I1 )) );
I0 ^= (I1 << 8) | (I1 >> 24);
I1 ^= (I0 << 16) | (I0 >> 16);
@@ -407,8 +353,8 @@ int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
* Prepare SIGMA values
*/
for( i = 0; i < 6; i++ ) {
- GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 );
- GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 );
+ SIGMA[i][0] = MBEDTLS_GET_UINT32_BE( SIGMA_CHARS[i], 0 );
+ SIGMA[i][1] = MBEDTLS_GET_UINT32_BE( SIGMA_CHARS[i], 4 );
}
/*
@@ -419,7 +365,7 @@ int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
/* Store KL, KR */
for( i = 0; i < 8; i++ )
- GET_UINT32_BE( KC[i], t, i * 4 );
+ KC[i] = MBEDTLS_GET_UINT32_BE( t, i * 4 );
/* Generate KA */
for( i = 0; i < 4; ++i )
@@ -545,10 +491,10 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
NR = ctx->nr;
RK = ctx->rk;
- GET_UINT32_BE( X[0], input, 0 );
- GET_UINT32_BE( X[1], input, 4 );
- GET_UINT32_BE( X[2], input, 8 );
- GET_UINT32_BE( X[3], input, 12 );
+ X[0] = MBEDTLS_GET_UINT32_BE( input, 0 );
+ X[1] = MBEDTLS_GET_UINT32_BE( input, 4 );
+ X[2] = MBEDTLS_GET_UINT32_BE( input, 8 );
+ X[3] = MBEDTLS_GET_UINT32_BE( input, 12 );
X[0] ^= *RK++;
X[1] ^= *RK++;
@@ -583,10 +529,10 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
X[0] ^= *RK++;
X[1] ^= *RK++;
- PUT_UINT32_BE( X[2], output, 0 );
- PUT_UINT32_BE( X[3], output, 4 );
- PUT_UINT32_BE( X[0], output, 8 );
- PUT_UINT32_BE( X[1], output, 12 );
+ MBEDTLS_PUT_UINT32_BE( X[2], output, 0 );
+ MBEDTLS_PUT_UINT32_BE( X[3], output, 4 );
+ MBEDTLS_PUT_UINT32_BE( X[0], output, 8 );
+ MBEDTLS_PUT_UINT32_BE( X[1], output, 12 );
return( 0 );
}
diff --git a/thirdparty/mbedtls/library/ccm.c b/thirdparty/mbedtls/library/ccm.c
index b2e5a4763d..a21a37f55f 100644
--- a/thirdparty/mbedtls/library/ccm.c
+++ b/thirdparty/mbedtls/library/ccm.c
@@ -2,13 +2,7 @@
* NIST SP800-38C compliant CCM implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -53,16 +26,13 @@
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CCM_C)
#include "mbedtls/ccm.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -99,13 +69,14 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
const unsigned char *key,
unsigned int keybits )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
CCM_VALIDATE_RET( ctx != NULL );
CCM_VALIDATE_RET( key != NULL );
- cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
+ cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
+ MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -180,7 +151,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char i;
unsigned char q;
size_t len_left, olen;
@@ -204,7 +175,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
if( iv_len < 7 || iv_len > 13 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
- if( add_len > 0xFF00 )
+ if( add_len >= 0xFF00 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
q = 16 - 1 - (unsigned char) iv_len;
@@ -229,7 +200,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
memcpy( b + 1, iv, iv_len );
for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
- b[15-i] = (unsigned char)( len_left & 0xFF );
+ b[15-i] = MBEDTLS_BYTE_0( len_left );
if( len_left > 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -250,8 +221,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
src = add;
memset( b, 0, 16 );
- b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
- b[1] = (unsigned char)( ( add_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( add_len, b, 0 );
use_len = len_left < 16 - 2 ? len_left : 16 - 2;
memcpy( b + 2, src, use_len );
@@ -390,7 +360,7 @@ int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
unsigned char i;
int diff;
@@ -454,34 +424,34 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
/*
* The data is the same for all tests, only the used length changes
*/
-static const unsigned char key[] = {
+static const unsigned char key_test_data[] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
};
-static const unsigned char iv[] = {
+static const unsigned char iv_test_data[] = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b
};
-static const unsigned char ad[] = {
+static const unsigned char ad_test_data[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13
};
-static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = {
+static const unsigned char msg_test_data[CCM_SELFTEST_PT_MAX_LEN] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
};
-static const size_t iv_len [NB_TESTS] = { 7, 8, 12 };
-static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
-static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
-static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
+static const size_t iv_len_test_data [NB_TESTS] = { 7, 8, 12 };
+static const size_t add_len_test_data[NB_TESTS] = { 8, 16, 20 };
+static const size_t msg_len_test_data[NB_TESTS] = { 4, 16, 24 };
+static const size_t tag_len_test_data[NB_TESTS] = { 4, 6, 8 };
-static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
+static const unsigned char res_test_data[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
@@ -503,11 +473,12 @@ int mbedtls_ccm_self_test( int verbose )
unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
size_t i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ccm_init( &ctx );
- if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
+ if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key_test_data,
+ 8 * sizeof key_test_data ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( " CCM: setup failed" );
@@ -522,15 +493,18 @@ int mbedtls_ccm_self_test( int verbose )
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
- memcpy( plaintext, msg, msg_len[i] );
+ memcpy( plaintext, msg_test_data, msg_len_test_data[i] );
- ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
- iv, iv_len[i], ad, add_len[i],
+ ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len_test_data[i],
+ iv_test_data, iv_len_test_data[i],
+ ad_test_data, add_len_test_data[i],
plaintext, ciphertext,
- ciphertext + msg_len[i], tag_len[i] );
+ ciphertext + msg_len_test_data[i],
+ tag_len_test_data[i] );
if( ret != 0 ||
- memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 )
+ memcmp( ciphertext, res_test_data[i],
+ msg_len_test_data[i] + tag_len_test_data[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
@@ -539,13 +513,15 @@ int mbedtls_ccm_self_test( int verbose )
}
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
- ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
- iv, iv_len[i], ad, add_len[i],
+ ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len_test_data[i],
+ iv_test_data, iv_len_test_data[i],
+ ad_test_data, add_len_test_data[i],
ciphertext, plaintext,
- ciphertext + msg_len[i], tag_len[i] );
+ ciphertext + msg_len_test_data[i],
+ tag_len_test_data[i] );
if( ret != 0 ||
- memcmp( plaintext, msg, msg_len[i] ) != 0 )
+ memcmp( plaintext, msg_test_data, msg_len_test_data[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
diff --git a/thirdparty/mbedtls/library/certs.c b/thirdparty/mbedtls/library/certs.c
index cb43f53368..a5695e3c8e 100644
--- a/thirdparty/mbedtls/library/certs.c
+++ b/thirdparty/mbedtls/library/certs.c
@@ -2,13 +2,7 @@
* X.509 test certificates
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#include "mbedtls/certs.h"
@@ -279,7 +248,7 @@
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \
"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \
- "MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \
+ "MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \
"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \
"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \
"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \
@@ -289,88 +258,88 @@
"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \
"UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \
"MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBBQUA\r\n" \
- "A4IBAQB0ZiNRFdia6kskaPnhrqejIRq8YMEGAf2oIPnyZ78xoyERgc35lHGyMtsL\r\n" \
- "hWicNjP4d/hS9As4j5KA2gdNGi5ETA1X7SowWOGsryivSpMSHVy1+HdfWlsYQOzm\r\n" \
- "8o+faQNUm8XzPVmttfAVspxeHSxJZ36Oo+QWZ5wZlCIEyjEdLUId+Tm4Bz3B5jRD\r\n" \
- "zZa/SaqDokq66N2zpbgKKAl3GU2O++fBqP2dSkdQykmTxhLLWRN8FJqhYATyQntZ\r\n" \
- "0QSi3W9HfSZPnFTcPIXeoiPd2pLlxt1hZu8dws2LTXE63uP6MM4LHvWxiuJaWkP/\r\n" \
- "mtxyUALj2pQxRitopORFQdn7AOY5\r\n" \
+ "A4IBAQABE3OEPfEd/bcJW5ZdU3/VgPNS4tMzh8gnJP/V2FcvFtGylMpQq6YnEBYI\r\n" \
+ "yBHAL4DRvlMY5rnXGBp3ODR8MpqHC6AquRTCLzjS57iYff//4QFQqW9n92zctspv\r\n" \
+ "czkaPKgjqo1No3Uq0Xaz10rcxyTUPrf5wNVRZ2V0KvllvAAVSzbI4mpdUXztjhST\r\n" \
+ "S5A2BeWQAAOr0zq1F7TSRVJpJs7jmB2ai/igkh1IAjcuwV6VwlP+sbw0gjQ0NpGM\r\n" \
+ "iHpnlzRAi/tIbtOvMIGOBU2TIfax/5jq1agUx5aPmT5TWAiJPOOP6l5xXnDwxeYS\r\n" \
+ "NWqiX9GyusBZjezaCaHabjDLU0qQ\r\n" \
"-----END CERTIFICATE-----\r\n"
/* END FILE */
/* This is taken from tests/data_files/test-ca-sha1.crt.der. */
/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA1_DER tests/data_files/test-ca-sha1.crt.der */
#define TEST_CA_CRT_RSA_SHA1_DER { \
- 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \
- 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
- 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
- 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
- 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
- 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
- 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \
- 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \
- 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
- 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
- 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
- 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \
- 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \
- 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \
- 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \
- 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \
- 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \
- 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \
- 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \
- 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \
- 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \
- 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \
- 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \
- 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \
- 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \
- 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \
- 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \
- 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \
- 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \
- 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \
- 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \
- 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \
- 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \
- 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \
- 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \
- 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \
- 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \
- 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \
- 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \
- 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \
- 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \
- 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, \
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0x66, 0x23, 0x51, 0x15, 0xd8, 0x9a, \
- 0xea, 0x4b, 0x24, 0x68, 0xf9, 0xe1, 0xae, 0xa7, 0xa3, 0x21, 0x1a, 0xbc, \
- 0x60, 0xc1, 0x06, 0x01, 0xfd, 0xa8, 0x20, 0xf9, 0xf2, 0x67, 0xbf, 0x31, \
- 0xa3, 0x21, 0x11, 0x81, 0xcd, 0xf9, 0x94, 0x71, 0xb2, 0x32, 0xdb, 0x0b, \
- 0x85, 0x68, 0x9c, 0x36, 0x33, 0xf8, 0x77, 0xf8, 0x52, 0xf4, 0x0b, 0x38, \
- 0x8f, 0x92, 0x80, 0xda, 0x07, 0x4d, 0x1a, 0x2e, 0x44, 0x4c, 0x0d, 0x57, \
- 0xed, 0x2a, 0x30, 0x58, 0xe1, 0xac, 0xaf, 0x28, 0xaf, 0x4a, 0x93, 0x12, \
- 0x1d, 0x5c, 0xb5, 0xf8, 0x77, 0x5f, 0x5a, 0x5b, 0x18, 0x40, 0xec, 0xe6, \
- 0xf2, 0x8f, 0x9f, 0x69, 0x03, 0x54, 0x9b, 0xc5, 0xf3, 0x3d, 0x59, 0xad, \
- 0xb5, 0xf0, 0x15, 0xb2, 0x9c, 0x5e, 0x1d, 0x2c, 0x49, 0x67, 0x7e, 0x8e, \
- 0xa3, 0xe4, 0x16, 0x67, 0x9c, 0x19, 0x94, 0x22, 0x04, 0xca, 0x31, 0x1d, \
- 0x2d, 0x42, 0x1d, 0xf9, 0x39, 0xb8, 0x07, 0x3d, 0xc1, 0xe6, 0x34, 0x43, \
- 0xcd, 0x96, 0xbf, 0x49, 0xaa, 0x83, 0xa2, 0x4a, 0xba, 0xe8, 0xdd, 0xb3, \
- 0xa5, 0xb8, 0x0a, 0x28, 0x09, 0x77, 0x19, 0x4d, 0x8e, 0xfb, 0xe7, 0xc1, \
- 0xa8, 0xfd, 0x9d, 0x4a, 0x47, 0x50, 0xca, 0x49, 0x93, 0xc6, 0x12, 0xcb, \
- 0x59, 0x13, 0x7c, 0x14, 0x9a, 0xa1, 0x60, 0x04, 0xf2, 0x42, 0x7b, 0x59, \
- 0xd1, 0x04, 0xa2, 0xdd, 0x6f, 0x47, 0x7d, 0x26, 0x4f, 0x9c, 0x54, 0xdc, \
- 0x3c, 0x85, 0xde, 0xa2, 0x23, 0xdd, 0xda, 0x92, 0xe5, 0xc6, 0xdd, 0x61, \
- 0x66, 0xef, 0x1d, 0xc2, 0xcd, 0x8b, 0x4d, 0x71, 0x3a, 0xde, 0xe3, 0xfa, \
- 0x30, 0xce, 0x0b, 0x1e, 0xf5, 0xb1, 0x8a, 0xe2, 0x5a, 0x5a, 0x43, 0xff, \
- 0x9a, 0xdc, 0x72, 0x50, 0x02, 0xe3, 0xda, 0x94, 0x31, 0x46, 0x2b, 0x68, \
- 0xa4, 0xe4, 0x45, 0x41, 0xd9, 0xfb, 0x00, 0xe6, 0x39 \
+ 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \
+ 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
+ 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
+ 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
+ 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
+ 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
+ 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \
+ 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \
+ 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
+ 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
+ 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
+ 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \
+ 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \
+ 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \
+ 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \
+ 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \
+ 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \
+ 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \
+ 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \
+ 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \
+ 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \
+ 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \
+ 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \
+ 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \
+ 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \
+ 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \
+ 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \
+ 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \
+ 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \
+ 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \
+ 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \
+ 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \
+ 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \
+ 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \
+ 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \
+ 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \
+ 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \
+ 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \
+ 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \
+ 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \
+ 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \
+ 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, \
+ 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x13, 0x73, 0x84, 0x3d, 0xf1, 0x1d, \
+ 0xfd, 0xb7, 0x09, 0x5b, 0x96, 0x5d, 0x53, 0x7f, 0xd5, 0x80, 0xf3, 0x52, \
+ 0xe2, 0xd3, 0x33, 0x87, 0xc8, 0x27, 0x24, 0xff, 0xd5, 0xd8, 0x57, 0x2f, \
+ 0x16, 0xd1, 0xb2, 0x94, 0xca, 0x50, 0xab, 0xa6, 0x27, 0x10, 0x16, 0x08, \
+ 0xc8, 0x11, 0xc0, 0x2f, 0x80, 0xd1, 0xbe, 0x53, 0x18, 0xe6, 0xb9, 0xd7, \
+ 0x18, 0x1a, 0x77, 0x38, 0x34, 0x7c, 0x32, 0x9a, 0x87, 0x0b, 0xa0, 0x2a, \
+ 0xb9, 0x14, 0xc2, 0x2f, 0x38, 0xd2, 0xe7, 0xb8, 0x98, 0x7d, 0xff, 0xff, \
+ 0xe1, 0x01, 0x50, 0xa9, 0x6f, 0x67, 0xf7, 0x6c, 0xdc, 0xb6, 0xca, 0x6f, \
+ 0x73, 0x39, 0x1a, 0x3c, 0xa8, 0x23, 0xaa, 0x8d, 0x4d, 0xa3, 0x75, 0x2a, \
+ 0xd1, 0x76, 0xb3, 0xd7, 0x4a, 0xdc, 0xc7, 0x24, 0xd4, 0x3e, 0xb7, 0xf9, \
+ 0xc0, 0xd5, 0x51, 0x67, 0x65, 0x74, 0x2a, 0xf9, 0x65, 0xbc, 0x00, 0x15, \
+ 0x4b, 0x36, 0xc8, 0xe2, 0x6a, 0x5d, 0x51, 0x7c, 0xed, 0x8e, 0x14, 0x93, \
+ 0x4b, 0x90, 0x36, 0x05, 0xe5, 0x90, 0x00, 0x03, 0xab, 0xd3, 0x3a, 0xb5, \
+ 0x17, 0xb4, 0xd2, 0x45, 0x52, 0x69, 0x26, 0xce, 0xe3, 0x98, 0x1d, 0x9a, \
+ 0x8b, 0xf8, 0xa0, 0x92, 0x1d, 0x48, 0x02, 0x37, 0x2e, 0xc1, 0x5e, 0x95, \
+ 0xc2, 0x53, 0xfe, 0xb1, 0xbc, 0x34, 0x82, 0x34, 0x34, 0x36, 0x91, 0x8c, \
+ 0x88, 0x7a, 0x67, 0x97, 0x34, 0x40, 0x8b, 0xfb, 0x48, 0x6e, 0xd3, 0xaf, \
+ 0x30, 0x81, 0x8e, 0x05, 0x4d, 0x93, 0x21, 0xf6, 0xb1, 0xff, 0x98, 0xea, \
+ 0xd5, 0xa8, 0x14, 0xc7, 0x96, 0x8f, 0x99, 0x3e, 0x53, 0x58, 0x08, 0x89, \
+ 0x3c, 0xe3, 0x8f, 0xea, 0x5e, 0x71, 0x5e, 0x70, 0xf0, 0xc5, 0xe6, 0x12, \
+ 0x35, 0x6a, 0xa2, 0x5f, 0xd1, 0xb2, 0xba, 0xc0, 0x59, 0x8d, 0xec, 0xda, \
+ 0x09, 0xa1, 0xda, 0x6e, 0x30, 0xcb, 0x53, 0x4a, 0x90 \
}
/* END FILE */
@@ -730,101 +699,101 @@
/* This is taken from tests/data_files/server2.crt. */
/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA1_PEM tests/data_files/server2.crt */
-#define TEST_SRV_CRT_RSA_SHA1_PEM \
- "-----BEGIN CERTIFICATE-----\r\n" \
- "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \
- "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \
- "MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \
- "A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \
- "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \
- "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \
- "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \
- "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \
- "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \
- "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \
- "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \
- "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJklg3Q4\r\n" \
- "cB7v7BzsxM/vLyKccO6op0/gZzM4ghuLq2Y32kl0sM6kSNUUmduuq3u/+GmUZN2A\r\n" \
- "O/7c+Hw7hDFEIvZk98aBGjCLqn3DmgHIv8ToQ67nellQxx2Uj309PdgjNi/r9HOc\r\n" \
- "KNAYPbBcg6MJGWWj2TI6vNaceios/DhOYx5V0j5nfqSJ/pnU0g9Ign2LAhgYpGJE\r\n" \
- "iEM9wW7hEMkwmk0h/sqZsrJsGH5YsF/VThSq/JVO1e2mZH2vruyZKJVBq+8tDNYp\r\n" \
- "HkK6tSyVYQhzIt3StMJWKMl/o5k2AYz6tSC164+1oG+ML3LWg8XrGKa91H4UOKap\r\n" \
- "Awgk0+4m0T25cNs=\r\n" \
- "-----END CERTIFICATE-----\r\n"
+#define TEST_SRV_CRT_RSA_SHA1_PEM \
+"-----BEGIN CERTIFICATE-----\r\n" \
+"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \
+"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \
+"MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \
+"A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \
+"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \
+"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \
+"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \
+"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \
+"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \
+"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \
+"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \
+"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJklg3Q4\r\n" \
+"cB7v7BzsxM/vLyKccO6op0/gZzM4ghuLq2Y32kl0sM6kSNUUmduuq3u/+GmUZN2A\r\n" \
+"O/7c+Hw7hDFEIvZk98aBGjCLqn3DmgHIv8ToQ67nellQxx2Uj309PdgjNi/r9HOc\r\n" \
+"KNAYPbBcg6MJGWWj2TI6vNaceios/DhOYx5V0j5nfqSJ/pnU0g9Ign2LAhgYpGJE\r\n" \
+"iEM9wW7hEMkwmk0h/sqZsrJsGH5YsF/VThSq/JVO1e2mZH2vruyZKJVBq+8tDNYp\r\n" \
+"HkK6tSyVYQhzIt3StMJWKMl/o5k2AYz6tSC164+1oG+ML3LWg8XrGKa91H4UOKap\r\n" \
+"Awgk0+4m0T25cNs=\r\n" \
+"-----END CERTIFICATE-----\r\n"
/* END FILE */
/* This is taken from tests/data_files/server2.crt.der. */
/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA1_DER tests/data_files/server2.crt.der */
#define TEST_SRV_CRT_RSA_SHA1_DER { \
- 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \
- 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
- 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
- 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
- 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
- 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
- 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \
- 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \
- 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
- 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
- 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
- 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \
- 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \
- 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \
- 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \
- 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \
- 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \
- 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \
- 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \
- 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \
- 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \
- 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \
- 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \
- 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \
- 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \
- 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \
- 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \
- 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \
- 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \
- 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \
- 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \
- 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \
- 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \
- 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \
- 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \
- 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \
- 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \
- 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \
- 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \
- 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \
- 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \
- 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, \
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x99, 0x25, 0x83, 0x74, 0x38, \
- 0x70, 0x1e, 0xef, 0xec, 0x1c, 0xec, 0xc4, 0xcf, 0xef, 0x2f, 0x22, 0x9c, \
- 0x70, 0xee, 0xa8, 0xa7, 0x4f, 0xe0, 0x67, 0x33, 0x38, 0x82, 0x1b, 0x8b, \
- 0xab, 0x66, 0x37, 0xda, 0x49, 0x74, 0xb0, 0xce, 0xa4, 0x48, 0xd5, 0x14, \
- 0x99, 0xdb, 0xae, 0xab, 0x7b, 0xbf, 0xf8, 0x69, 0x94, 0x64, 0xdd, 0x80, \
- 0x3b, 0xfe, 0xdc, 0xf8, 0x7c, 0x3b, 0x84, 0x31, 0x44, 0x22, 0xf6, 0x64, \
- 0xf7, 0xc6, 0x81, 0x1a, 0x30, 0x8b, 0xaa, 0x7d, 0xc3, 0x9a, 0x01, 0xc8, \
- 0xbf, 0xc4, 0xe8, 0x43, 0xae, 0xe7, 0x7a, 0x59, 0x50, 0xc7, 0x1d, 0x94, \
- 0x8f, 0x7d, 0x3d, 0x3d, 0xd8, 0x23, 0x36, 0x2f, 0xeb, 0xf4, 0x73, 0x9c, \
- 0x28, 0xd0, 0x18, 0x3d, 0xb0, 0x5c, 0x83, 0xa3, 0x09, 0x19, 0x65, 0xa3, \
- 0xd9, 0x32, 0x3a, 0xbc, 0xd6, 0x9c, 0x7a, 0x2a, 0x2c, 0xfc, 0x38, 0x4e, \
- 0x63, 0x1e, 0x55, 0xd2, 0x3e, 0x67, 0x7e, 0xa4, 0x89, 0xfe, 0x99, 0xd4, \
- 0xd2, 0x0f, 0x48, 0x82, 0x7d, 0x8b, 0x02, 0x18, 0x18, 0xa4, 0x62, 0x44, \
- 0x88, 0x43, 0x3d, 0xc1, 0x6e, 0xe1, 0x10, 0xc9, 0x30, 0x9a, 0x4d, 0x21, \
- 0xfe, 0xca, 0x99, 0xb2, 0xb2, 0x6c, 0x18, 0x7e, 0x58, 0xb0, 0x5f, 0xd5, \
- 0x4e, 0x14, 0xaa, 0xfc, 0x95, 0x4e, 0xd5, 0xed, 0xa6, 0x64, 0x7d, 0xaf, \
- 0xae, 0xec, 0x99, 0x28, 0x95, 0x41, 0xab, 0xef, 0x2d, 0x0c, 0xd6, 0x29, \
- 0x1e, 0x42, 0xba, 0xb5, 0x2c, 0x95, 0x61, 0x08, 0x73, 0x22, 0xdd, 0xd2, \
- 0xb4, 0xc2, 0x56, 0x28, 0xc9, 0x7f, 0xa3, 0x99, 0x36, 0x01, 0x8c, 0xfa, \
- 0xb5, 0x20, 0xb5, 0xeb, 0x8f, 0xb5, 0xa0, 0x6f, 0x8c, 0x2f, 0x72, 0xd6, \
- 0x83, 0xc5, 0xeb, 0x18, 0xa6, 0xbd, 0xd4, 0x7e, 0x14, 0x38, 0xa6, 0xa9, \
- 0x03, 0x08, 0x24, 0xd3, 0xee, 0x26, 0xd1, 0x3d, 0xb9, 0x70, 0xdb \
+ 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \
+ 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
+ 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
+ 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
+ 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
+ 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
+ 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \
+ 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \
+ 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
+ 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
+ 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
+ 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \
+ 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \
+ 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \
+ 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \
+ 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \
+ 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \
+ 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \
+ 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \
+ 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \
+ 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \
+ 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \
+ 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \
+ 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \
+ 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \
+ 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \
+ 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \
+ 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \
+ 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \
+ 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \
+ 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \
+ 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \
+ 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \
+ 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \
+ 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \
+ 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \
+ 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \
+ 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \
+ 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \
+ 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \
+ 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \
+ 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, \
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x73, 0x0b, 0x4a, 0xc5, \
+ 0xcb, 0xa0, 0xde, 0xf1, 0x63, 0x1c, 0x76, 0x04, 0x2b, 0x13, 0x0d, 0xc0, \
+ 0x84, 0x11, 0xc5, 0x8f, 0x3a, 0xa7, 0xc5, 0x9c, 0x35, 0x7a, 0x77, 0xb8, \
+ 0x20, 0x14, 0x82, 0xee, 0x54, 0xf0, 0xf2, 0xb0, 0x52, 0xcb, 0x78, 0xce, \
+ 0x59, 0x07, 0x4f, 0x51, 0x69, 0xfe, 0xd3, 0x2f, 0xe9, 0x09, 0xe7, 0x85, \
+ 0x92, 0xd8, 0xba, 0xb1, 0xeb, 0xc5, 0x76, 0x5d, 0x61, 0x2d, 0xe9, 0x86, \
+ 0xb5, 0xde, 0x2a, 0xf9, 0x3f, 0x53, 0x28, 0x42, 0x86, 0x83, 0x73, 0x43, \
+ 0xe0, 0x04, 0x5f, 0x07, 0x90, 0x14, 0x65, 0x9f, 0x6e, 0x10, 0x7a, 0xbc, \
+ 0x58, 0x19, 0x22, 0xc2, 0xeb, 0x39, 0x72, 0x51, 0x92, 0xd7, 0xb4, 0x1d, \
+ 0x75, 0x2f, 0xd3, 0x3a, 0x2b, 0x01, 0xe7, 0xdb, 0x50, 0xae, 0xe2, 0xf1, \
+ 0xd4, 0x4d, 0x5b, 0x3c, 0xbb, 0x41, 0x2b, 0x2a, 0xa4, 0xe2, 0x4a, 0x02, \
+ 0xe5, 0x60, 0x14, 0x2c, 0x9c, 0x1f, 0xa6, 0xcc, 0x06, 0x4b, 0x25, 0x89, \
+ 0x4e, 0x96, 0x30, 0x22, 0x9c, 0x5c, 0x58, 0x4d, 0xc3, 0xda, 0xd0, 0x6e, \
+ 0x50, 0x1e, 0x8c, 0x65, 0xf5, 0xd9, 0x17, 0x35, 0xa6, 0x58, 0x43, 0xb2, \
+ 0x29, 0xb7, 0xa8, 0x5e, 0x35, 0xde, 0xf0, 0x60, 0x42, 0x1a, 0x01, 0xcb, \
+ 0xcb, 0x0b, 0xd8, 0x0e, 0xc1, 0x90, 0xdf, 0xa1, 0xd2, 0x1a, 0xd1, 0x2c, \
+ 0x02, 0xf4, 0x76, 0x41, 0xa4, 0xcb, 0x4b, 0x15, 0x98, 0x71, 0xf9, 0x35, \
+ 0x7d, 0xb0, 0xe7, 0xe2, 0x34, 0x96, 0x91, 0xbe, 0x32, 0x67, 0x2d, 0x6b, \
+ 0xd3, 0x55, 0x04, 0x8a, 0x01, 0x50, 0xb4, 0xe3, 0x62, 0x78, 0x6c, 0x11, \
+ 0x15, 0xa5, 0x2a, 0x11, 0xc1, 0x49, 0x1c, 0x9b, 0xc4, 0x10, 0x65, 0x60, \
+ 0x87, 0xd9, 0x1e, 0x69, 0x59, 0x4e, 0x8f, 0x6b, 0xeb, 0xc1, 0xfe, 0x6b, \
+ 0xe2, 0x63, 0x78, 0x95, 0x6e, 0xe0, 0x2d, 0xd7, 0xa7, 0x37, 0xa8 \
}
/* END FILE */
@@ -993,54 +962,54 @@
"IwQYMBaAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8MAwGCCqGSM49BAMCBQADaAAwZQIx\r\n" \
"AMqme4DKMldUlplDET9Q6Eptre7uUWKhsLOF+zPkKDlfzpIkJYEFgcloDHGYw80u\r\n" \
"IgIwNftyPXsabTqMM7iEHgVpX/GRozKklY9yQI/5eoA6gGW7Y+imuGR/oao5ySOb\r\n" \
- "a9Vk\r\n" \
+ "a9Vk\r\n" \
"-----END CERTIFICATE-----\r\n"
/* END FILE */
/* This is generated from tests/data_files/cli2.crt.der using `xxd -i`. */
/* BEGIN FILE binary macro TEST_CLI_CRT_EC_DER tests/data_files/cli2.crt.der */
#define TEST_CLI_CRT_EC_DER { \
- 0x30, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01, 0x63, 0xa0, 0x03, 0x02, 0x01, \
- 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \
- 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \
- 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \
- 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \
- 0x03, 0x0c, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, \
- 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, \
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, \
- 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, \
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \
- 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \
- 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, \
- 0x03, 0x0c, 0x16, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, \
- 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, \
- 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, \
- 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, 0xb1, 0x73, 0xdf, 0xd3, 0xac, \
- 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, 0xee, 0xe6, 0x53, 0xac, 0xce, \
- 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, 0xe3, 0x63, 0x25, 0x0b, 0xdf, \
- 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, 0xc0, 0xd5, 0x18, 0x14, 0x70, \
- 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, \
- 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, 0xc7, 0xa3, 0x4d, 0x30, 0x4b, \
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, \
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7a, 0x00, \
- 0x5f, 0x86, 0x64, 0xfc, 0xe0, 0x5d, 0xe5, 0x11, 0x10, 0x3b, 0xb2, 0xe6, \
- 0x3b, 0xc4, 0x26, 0x3f, 0xcf, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, \
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, \
- 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, \
- 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \
- 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, \
- 0x00, 0xca, 0xa6, 0x7b, 0x80, 0xca, 0x32, 0x57, 0x54, 0x96, 0x99, 0x43, \
- 0x11, 0x3f, 0x50, 0xe8, 0x4a, 0x6d, 0xad, 0xee, 0xee, 0x51, 0x62, 0xa1, \
- 0xb0, 0xb3, 0x85, 0xfb, 0x33, 0xe4, 0x28, 0x39, 0x5f, 0xce, 0x92, 0x24, \
- 0x25, 0x81, 0x05, 0x81, 0xc9, 0x68, 0x0c, 0x71, 0x98, 0xc3, 0xcd, 0x2e, \
- 0x22, 0x02, 0x30, 0x35, 0xfb, 0x72, 0x3d, 0x7b, 0x1a, 0x6d, 0x3a, 0x8c, \
- 0x33, 0xb8, 0x84, 0x1e, 0x05, 0x69, 0x5f, 0xf1, 0x91, 0xa3, 0x32, 0xa4, \
- 0x95, 0x8f, 0x72, 0x40, 0x8f, 0xf9, 0x7a, 0x80, 0x3a, 0x80, 0x65, 0xbb, \
- 0x63, 0xe8, 0xa6, 0xb8, 0x64, 0x7f, 0xa1, 0xaa, 0x39, 0xc9, 0x23, 0x9b, \
- 0x6b, 0xd5, 0x64 \
+ 0x30, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01, 0x63, 0xa0, 0x03, 0x02, 0x01, \
+ 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \
+ 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \
+ 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \
+ 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \
+ 0x03, 0x0c, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, \
+ 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, \
+ 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, \
+ 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, \
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \
+ 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \
+ 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, \
+ 0x03, 0x0c, 0x16, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, \
+ 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, \
+ 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, \
+ 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, 0xb1, 0x73, 0xdf, 0xd3, 0xac, \
+ 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, 0xee, 0xe6, 0x53, 0xac, 0xce, \
+ 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, 0xe3, 0x63, 0x25, 0x0b, 0xdf, \
+ 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, 0xc0, 0xd5, 0x18, 0x14, 0x70, \
+ 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, \
+ 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, 0xc7, 0xa3, 0x4d, 0x30, 0x4b, \
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, \
+ 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7a, 0x00, \
+ 0x5f, 0x86, 0x64, 0xfc, 0xe0, 0x5d, 0xe5, 0x11, 0x10, 0x3b, 0xb2, 0xe6, \
+ 0x3b, 0xc4, 0x26, 0x3f, 0xcf, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, \
+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, \
+ 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, \
+ 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \
+ 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, \
+ 0x00, 0xca, 0xa6, 0x7b, 0x80, 0xca, 0x32, 0x57, 0x54, 0x96, 0x99, 0x43, \
+ 0x11, 0x3f, 0x50, 0xe8, 0x4a, 0x6d, 0xad, 0xee, 0xee, 0x51, 0x62, 0xa1, \
+ 0xb0, 0xb3, 0x85, 0xfb, 0x33, 0xe4, 0x28, 0x39, 0x5f, 0xce, 0x92, 0x24, \
+ 0x25, 0x81, 0x05, 0x81, 0xc9, 0x68, 0x0c, 0x71, 0x98, 0xc3, 0xcd, 0x2e, \
+ 0x22, 0x02, 0x30, 0x35, 0xfb, 0x72, 0x3d, 0x7b, 0x1a, 0x6d, 0x3a, 0x8c, \
+ 0x33, 0xb8, 0x84, 0x1e, 0x05, 0x69, 0x5f, 0xf1, 0x91, 0xa3, 0x32, 0xa4, \
+ 0x95, 0x8f, 0x72, 0x40, 0x8f, 0xf9, 0x7a, 0x80, 0x3a, 0x80, 0x65, 0xbb, \
+ 0x63, 0xe8, 0xa6, 0xb8, 0x64, 0x7f, 0xa1, 0xaa, 0x39, 0xc9, 0x23, 0x9b, \
+ 0x6b, 0xd5, 0x64 \
}
/* END FILE */
@@ -1100,76 +1069,76 @@
using `xxd -i.` */
/* BEGIN FILE binary macro TEST_CLI_CRT_RSA_DER tests/data_files/cli-rsa-sha256.crt.der */
#define TEST_CLI_CRT_RSA_DER { \
- 0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0x27, 0xa0, 0x03, 0x02, 0x01, \
- 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
- 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
- 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
- 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
- 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
- 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \
- 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \
- 0x34, 0x30, 0x36, 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
- 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
- 0x53, 0x4c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
- 0x11, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x6c, \
- 0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, \
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, \
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, \
- 0x01, 0x01, 0x00, 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, \
- 0x45, 0xd9, 0x14, 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, \
- 0x33, 0xad, 0x0d, 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, \
- 0xcc, 0x66, 0x85, 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, \
- 0x9e, 0x0a, 0x6e, 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, \
- 0x93, 0x86, 0x49, 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, \
- 0xd4, 0x2f, 0x77, 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, \
- 0x48, 0x70, 0xf5, 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, \
- 0xe6, 0x43, 0xea, 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, \
- 0x57, 0x4e, 0xa9, 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, \
- 0x32, 0x30, 0xd5, 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, \
- 0x5f, 0xf9, 0x3d, 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, \
- 0xfb, 0xe5, 0x0c, 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, \
- 0x7f, 0xca, 0xad, 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, \
- 0xe0, 0x9b, 0xf8, 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, \
- 0x04, 0x66, 0xc7, 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, \
- 0x06, 0x67, 0xf4, 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, \
- 0x3c, 0x8b, 0x35, 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, \
- 0xfc, 0x36, 0x6b, 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, \
- 0x00, 0xcf, 0xaf, 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, \
- 0xe7, 0x50, 0x71, 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, \
- 0xe4, 0xc4, 0xfd, 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, \
- 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, \
- 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, \
- 0x04, 0x14, 0x71, 0xa1, 0x00, 0x73, 0x72, 0x40, 0x2f, 0x54, 0x76, 0x5e, \
- 0x33, 0xfc, 0x52, 0x8f, 0xbc, 0xf1, 0xdd, 0x6b, 0x46, 0x21, 0x30, 0x1f, \
- 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, \
- 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, 0xa6, 0x95, \
- 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, \
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, \
- 0x01, 0x01, 0x00, 0x5e, 0x27, 0x6f, 0xd5, 0xde, 0x29, 0x2e, 0x50, 0x62, \
- 0x29, 0x61, 0x03, 0xf7, 0x9a, 0xcc, 0xc9, 0xc0, 0x5d, 0x80, 0x37, 0x20, \
- 0xc8, 0xda, 0x89, 0xc5, 0xa9, 0x05, 0x91, 0x17, 0xd1, 0xc8, 0x0d, 0xb2, \
- 0xd6, 0x69, 0x72, 0x4e, 0x7e, 0xee, 0x05, 0x74, 0x64, 0x34, 0xb6, 0x39, \
- 0x64, 0x5c, 0xca, 0xf3, 0x61, 0x82, 0x8e, 0x4d, 0x90, 0xd8, 0xe0, 0xf8, \
- 0x45, 0x94, 0x82, 0x3c, 0x02, 0x49, 0xa8, 0xba, 0x47, 0x1d, 0x4d, 0xf8, \
- 0xb7, 0xbd, 0x5c, 0x89, 0xf7, 0xef, 0xcb, 0x62, 0x8a, 0xf3, 0x56, 0x2f, \
- 0xaf, 0x17, 0x33, 0x46, 0x13, 0x00, 0x13, 0xae, 0x22, 0xfa, 0xa9, 0xda, \
- 0xc8, 0xfd, 0xd3, 0x77, 0x65, 0xee, 0x58, 0x94, 0x74, 0xe4, 0xf5, 0x4f, \
- 0xa1, 0x27, 0xa6, 0xb0, 0xd1, 0x0b, 0xb3, 0xd8, 0x16, 0xb6, 0xd7, 0x67, \
- 0x63, 0x2d, 0xdc, 0x7b, 0xe1, 0x18, 0xd9, 0x8d, 0x27, 0xed, 0x1b, 0x22, \
- 0xef, 0xdf, 0x36, 0x11, 0xe2, 0xc8, 0x00, 0x0e, 0xc7, 0xe9, 0xc6, 0xb8, \
- 0xd8, 0x4b, 0x3f, 0x35, 0x41, 0xff, 0xfc, 0x96, 0x49, 0x4f, 0x7d, 0x8e, \
- 0x3f, 0x47, 0x68, 0x33, 0x17, 0x83, 0x44, 0x0f, 0xaf, 0xa6, 0x59, 0x0a, \
- 0xa9, 0x32, 0xcb, 0x59, 0xfe, 0xdd, 0x5f, 0x6e, 0x8b, 0x22, 0xb8, 0x81, \
- 0x90, 0x16, 0x91, 0x0a, 0x04, 0x79, 0x62, 0xff, 0x4b, 0x04, 0xf1, 0x5c, \
- 0x34, 0xeb, 0x69, 0xce, 0xef, 0xcb, 0x6e, 0xb6, 0x3b, 0x40, 0x55, 0xca, \
- 0x24, 0xc2, 0x3e, 0x25, 0x70, 0xee, 0x74, 0x2b, 0x0e, 0x9f, 0xc2, 0x82, \
- 0x9a, 0x20, 0x38, 0x77, 0xa1, 0x26, 0x8a, 0xca, 0x9f, 0x87, 0x75, 0x77, \
- 0xe3, 0xce, 0x65, 0xec, 0x71, 0x10, 0x35, 0xcb, 0xcb, 0x4f, 0x19, 0x43, \
- 0xeb, 0x30, 0xd0, 0xca, 0x2d, 0x3f, 0xca, 0x46, 0x14, 0x61, 0x99, 0x30, \
- 0x41, 0x32, 0xb5, 0x37, 0x63, 0x6f, 0x97 \
+ 0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0x27, 0xa0, 0x03, 0x02, 0x01, \
+ 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
+ 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
+ 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
+ 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
+ 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
+ 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \
+ 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \
+ 0x34, 0x30, 0x36, 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
+ 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
+ 0x53, 0x4c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
+ 0x11, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x6c, \
+ 0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, \
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, \
+ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, \
+ 0x01, 0x01, 0x00, 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, \
+ 0x45, 0xd9, 0x14, 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, \
+ 0x33, 0xad, 0x0d, 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, \
+ 0xcc, 0x66, 0x85, 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, \
+ 0x9e, 0x0a, 0x6e, 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, \
+ 0x93, 0x86, 0x49, 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, \
+ 0xd4, 0x2f, 0x77, 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, \
+ 0x48, 0x70, 0xf5, 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, \
+ 0xe6, 0x43, 0xea, 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, \
+ 0x57, 0x4e, 0xa9, 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, \
+ 0x32, 0x30, 0xd5, 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, \
+ 0x5f, 0xf9, 0x3d, 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, \
+ 0xfb, 0xe5, 0x0c, 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, \
+ 0x7f, 0xca, 0xad, 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, \
+ 0xe0, 0x9b, 0xf8, 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, \
+ 0x04, 0x66, 0xc7, 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, \
+ 0x06, 0x67, 0xf4, 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, \
+ 0x3c, 0x8b, 0x35, 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, \
+ 0xfc, 0x36, 0x6b, 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, \
+ 0x00, 0xcf, 0xaf, 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, \
+ 0xe7, 0x50, 0x71, 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, \
+ 0xe4, 0xc4, 0xfd, 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, \
+ 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, \
+ 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, \
+ 0x04, 0x14, 0x71, 0xa1, 0x00, 0x73, 0x72, 0x40, 0x2f, 0x54, 0x76, 0x5e, \
+ 0x33, 0xfc, 0x52, 0x8f, 0xbc, 0xf1, 0xdd, 0x6b, 0x46, 0x21, 0x30, 0x1f, \
+ 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, \
+ 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, 0xa6, 0x95, \
+ 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, \
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, \
+ 0x01, 0x01, 0x00, 0x5e, 0x27, 0x6f, 0xd5, 0xde, 0x29, 0x2e, 0x50, 0x62, \
+ 0x29, 0x61, 0x03, 0xf7, 0x9a, 0xcc, 0xc9, 0xc0, 0x5d, 0x80, 0x37, 0x20, \
+ 0xc8, 0xda, 0x89, 0xc5, 0xa9, 0x05, 0x91, 0x17, 0xd1, 0xc8, 0x0d, 0xb2, \
+ 0xd6, 0x69, 0x72, 0x4e, 0x7e, 0xee, 0x05, 0x74, 0x64, 0x34, 0xb6, 0x39, \
+ 0x64, 0x5c, 0xca, 0xf3, 0x61, 0x82, 0x8e, 0x4d, 0x90, 0xd8, 0xe0, 0xf8, \
+ 0x45, 0x94, 0x82, 0x3c, 0x02, 0x49, 0xa8, 0xba, 0x47, 0x1d, 0x4d, 0xf8, \
+ 0xb7, 0xbd, 0x5c, 0x89, 0xf7, 0xef, 0xcb, 0x62, 0x8a, 0xf3, 0x56, 0x2f, \
+ 0xaf, 0x17, 0x33, 0x46, 0x13, 0x00, 0x13, 0xae, 0x22, 0xfa, 0xa9, 0xda, \
+ 0xc8, 0xfd, 0xd3, 0x77, 0x65, 0xee, 0x58, 0x94, 0x74, 0xe4, 0xf5, 0x4f, \
+ 0xa1, 0x27, 0xa6, 0xb0, 0xd1, 0x0b, 0xb3, 0xd8, 0x16, 0xb6, 0xd7, 0x67, \
+ 0x63, 0x2d, 0xdc, 0x7b, 0xe1, 0x18, 0xd9, 0x8d, 0x27, 0xed, 0x1b, 0x22, \
+ 0xef, 0xdf, 0x36, 0x11, 0xe2, 0xc8, 0x00, 0x0e, 0xc7, 0xe9, 0xc6, 0xb8, \
+ 0xd8, 0x4b, 0x3f, 0x35, 0x41, 0xff, 0xfc, 0x96, 0x49, 0x4f, 0x7d, 0x8e, \
+ 0x3f, 0x47, 0x68, 0x33, 0x17, 0x83, 0x44, 0x0f, 0xaf, 0xa6, 0x59, 0x0a, \
+ 0xa9, 0x32, 0xcb, 0x59, 0xfe, 0xdd, 0x5f, 0x6e, 0x8b, 0x22, 0xb8, 0x81, \
+ 0x90, 0x16, 0x91, 0x0a, 0x04, 0x79, 0x62, 0xff, 0x4b, 0x04, 0xf1, 0x5c, \
+ 0x34, 0xeb, 0x69, 0xce, 0xef, 0xcb, 0x6e, 0xb6, 0x3b, 0x40, 0x55, 0xca, \
+ 0x24, 0xc2, 0x3e, 0x25, 0x70, 0xee, 0x74, 0x2b, 0x0e, 0x9f, 0xc2, 0x82, \
+ 0x9a, 0x20, 0x38, 0x77, 0xa1, 0x26, 0x8a, 0xca, 0x9f, 0x87, 0x75, 0x77, \
+ 0xe3, 0xce, 0x65, 0xec, 0x71, 0x10, 0x35, 0xcb, 0xcb, 0x4f, 0x19, 0x43, \
+ 0xeb, 0x30, 0xd0, 0xca, 0x2d, 0x3f, 0xca, 0x46, 0x14, 0x61, 0x99, 0x30, \
+ 0x41, 0x32, 0xb5, 0x37, 0x63, 0x6f, 0x97 \
}
/* END FILE */
@@ -1643,7 +1612,6 @@ const size_t mbedtls_test_srv_crt_rsa_len =
#define TEST_CLI_KEY TEST_CLI_KEY_EC
#define TEST_CLI_PWD TEST_CLI_PWD_EC
#define TEST_CLI_CRT TEST_CLI_CRT_EC
-
#endif /* MBEDTLS_RSA_C */
/* API stability forces us to declare
diff --git a/thirdparty/mbedtls/library/chacha20.c b/thirdparty/mbedtls/library/chacha20.c
index 80fe50cc67..658f046901 100644
--- a/thirdparty/mbedtls/library/chacha20.c
+++ b/thirdparty/mbedtls/library/chacha20.c
@@ -6,13 +6,7 @@
* \author Daniel King <damaki.gh@gmail.com>
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,39 +19,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CHACHA20_C)
#include "mbedtls/chacha20.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <stddef.h>
#include <string.h>
@@ -84,13 +54,6 @@
#define CHACHA20_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#define BYTES_TO_U32_LE( data, offset ) \
- ( (uint32_t) (data)[offset] \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
- )
-
#define ROTL32( value, amount ) \
( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
@@ -201,10 +164,7 @@ static void chacha20_block( const uint32_t initial_state[16],
{
size_t offset = i * 4U;
- keystream[offset ] = (unsigned char)( working_state[i] );
- keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 );
- keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
- keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
+ MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset);
}
mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
@@ -242,14 +202,14 @@ int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
ctx->state[3] = 0x6b206574;
/* Set key */
- ctx->state[4] = BYTES_TO_U32_LE( key, 0 );
- ctx->state[5] = BYTES_TO_U32_LE( key, 4 );
- ctx->state[6] = BYTES_TO_U32_LE( key, 8 );
- ctx->state[7] = BYTES_TO_U32_LE( key, 12 );
- ctx->state[8] = BYTES_TO_U32_LE( key, 16 );
- ctx->state[9] = BYTES_TO_U32_LE( key, 20 );
- ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
- ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
+ ctx->state[4] = MBEDTLS_GET_UINT32_LE( key, 0 );
+ ctx->state[5] = MBEDTLS_GET_UINT32_LE( key, 4 );
+ ctx->state[6] = MBEDTLS_GET_UINT32_LE( key, 8 );
+ ctx->state[7] = MBEDTLS_GET_UINT32_LE( key, 12 );
+ ctx->state[8] = MBEDTLS_GET_UINT32_LE( key, 16 );
+ ctx->state[9] = MBEDTLS_GET_UINT32_LE( key, 20 );
+ ctx->state[10] = MBEDTLS_GET_UINT32_LE( key, 24 );
+ ctx->state[11] = MBEDTLS_GET_UINT32_LE( key, 28 );
return( 0 );
}
@@ -265,9 +225,9 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
ctx->state[12] = counter;
/* Nonce */
- ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
- ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
- ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
+ ctx->state[13] = MBEDTLS_GET_UINT32_LE( nonce, 0 );
+ ctx->state[14] = MBEDTLS_GET_UINT32_LE( nonce, 4 );
+ ctx->state[15] = MBEDTLS_GET_UINT32_LE( nonce, 8 );
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
@@ -350,7 +310,7 @@ int mbedtls_chacha20_crypt( const unsigned char key[32],
unsigned char* output )
{
mbedtls_chacha20_context ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
CHACHA20_VALIDATE_RET( key != NULL );
CHACHA20_VALIDATE_RET( nonce != NULL );
@@ -544,6 +504,9 @@ static const size_t test_lengths[2] =
375U
};
+/* Make sure no other definition is already present. */
+#undef ASSERT
+
#define ASSERT( cond, args ) \
do \
{ \
@@ -561,7 +524,7 @@ int mbedtls_chacha20_self_test( int verbose )
{
unsigned char output[381];
unsigned i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
for( i = 0U; i < 2U; i++ )
{
diff --git a/thirdparty/mbedtls/library/chachapoly.c b/thirdparty/mbedtls/library/chachapoly.c
index c8b5bba4b2..dc75b2030a 100644
--- a/thirdparty/mbedtls/library/chachapoly.c
+++ b/thirdparty/mbedtls/library/chachapoly.c
@@ -4,13 +4,7 @@
* \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,38 +17,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -147,7 +117,7 @@ void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
const unsigned char key[32] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
CHACHAPOLY_VALIDATE_RET( key != NULL );
@@ -160,7 +130,7 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
const unsigned char nonce[12],
mbedtls_chachapoly_mode_t mode )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char poly1305_key[64];
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
CHACHAPOLY_VALIDATE_RET( nonce != NULL );
@@ -216,7 +186,7 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );
CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );
@@ -265,7 +235,7 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
unsigned char mac[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char len_block[16];
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
CHACHAPOLY_VALIDATE_RET( mac != NULL );
@@ -293,22 +263,8 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
/* The lengths of the AAD and ciphertext are processed by
* Poly1305 as the final 128-bit block, encoded as little-endian integers.
*/
- len_block[ 0] = (unsigned char)( ctx->aad_len );
- len_block[ 1] = (unsigned char)( ctx->aad_len >> 8 );
- len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 );
- len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 );
- len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 );
- len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 );
- len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 );
- len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 );
- len_block[ 8] = (unsigned char)( ctx->ciphertext_len );
- len_block[ 9] = (unsigned char)( ctx->ciphertext_len >> 8 );
- len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 );
- len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 );
- len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 );
- len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 );
- len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 );
- len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 );
+ MBEDTLS_PUT_UINT64_LE(ctx->aad_len, len_block, 0);
+ MBEDTLS_PUT_UINT64_LE(ctx->ciphertext_len, len_block, 8);
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
if( ret != 0 )
@@ -329,7 +285,7 @@ static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
unsigned char *output,
unsigned char tag[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_chachapoly_starts( ctx, nonce, mode );
if( ret != 0 )
@@ -379,7 +335,7 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
size_t i;
int diff;
@@ -500,6 +456,9 @@ static const unsigned char test_mac[1][16] =
}
};
+/* Make sure no other definition is already present. */
+#undef ASSERT
+
#define ASSERT( cond, args ) \
do \
{ \
@@ -517,7 +476,7 @@ int mbedtls_chachapoly_self_test( int verbose )
{
mbedtls_chachapoly_context ctx;
unsigned i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char output[200];
unsigned char mac[16];
diff --git a/thirdparty/mbedtls/library/check_crypto_config.h b/thirdparty/mbedtls/library/check_crypto_config.h
new file mode 100644
index 0000000000..d7ad16a617
--- /dev/null
+++ b/thirdparty/mbedtls/library/check_crypto_config.h
@@ -0,0 +1,91 @@
+/**
+ * \file check_crypto_config.h
+ *
+ * \brief Consistency checks for PSA configuration options
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * It is recommended to include this file from your crypto_config.h
+ * in order to catch dependency issues early.
+ */
+
+#ifndef MBEDTLS_CHECK_CRYPTO_CONFIG_H
+#define MBEDTLS_CHECK_CRYPTO_CONFIG_H
+
+#if defined(PSA_WANT_ALG_CCM) && \
+ !( defined(PSA_WANT_KEY_TYPE_AES) || \
+ defined(PSA_WANT_KEY_TYPE_CAMELLIA) )
+#error "PSA_WANT_ALG_CCM defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_CMAC) && \
+ !( defined(PSA_WANT_KEY_TYPE_AES) || \
+ defined(PSA_WANT_KEY_TYPE_CAMELLIA) || \
+ defined(PSA_WANT_KEY_TYPE_DES) )
+#error "PSA_WANT_ALG_CMAC defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
+ !( defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_DETERMINISTIC_ECDSA defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_ECDSA) && \
+ !( defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_ECDSA defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_GCM) && \
+ !( defined(PSA_WANT_KEY_TYPE_AES) || \
+ defined(PSA_WANT_KEY_TYPE_CAMELLIA) )
+#error "PSA_WANT_ALG_GCM defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \
+ !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \
+ !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_RSA_OAEP) && \
+ !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_RSA_PSS) && \
+ !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
+ !defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
+#error "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR defined, but not all prerequisites"
+#endif
+
+#endif /* MBEDTLS_CHECK_CRYPTO_CONFIG_H */
diff --git a/thirdparty/mbedtls/library/cipher.c b/thirdparty/mbedtls/library/cipher.c
index 4ea0221f4d..4ec40d2cac 100644
--- a/thirdparty/mbedtls/library/cipher.c
+++ b/thirdparty/mbedtls/library/cipher.c
@@ -6,13 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,40 +19,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#include "mbedtls/cipher_internal.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
#include <stdlib.h>
#include <string.h>
@@ -83,6 +54,15 @@
#include "mbedtls/cmac.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_NIST_KW_C)
+#include "mbedtls/nist_kw.h"
+#endif
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -95,26 +75,6 @@
#define CIPHER_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-/* Compare the contents of two buffers in constant time.
- * Returns 0 if the contents are bitwise identical, otherwise returns
- * a non-zero value.
- * This is currently only used by GCM and ChaCha20+Poly1305.
- */
-static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len )
-{
- const unsigned char *p1 = (const unsigned char*) v1;
- const unsigned char *p2 = (const unsigned char*) v2;
- size_t i;
- unsigned char diff;
-
- for( diff = 0, i = 0; i < len; i++ )
- diff |= p1[i] ^ p2[i];
-
- return( (int)diff );
-}
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
static int supported_init = 0;
const int *mbedtls_cipher_list( void )
@@ -138,7 +98,8 @@ const int *mbedtls_cipher_list( void )
return( mbedtls_cipher_supported );
}
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type )
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
+ const mbedtls_cipher_type_t cipher_type )
{
const mbedtls_cipher_definition_t *def;
@@ -149,7 +110,8 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher
return( NULL );
}
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name )
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
+ const char *cipher_name )
{
const mbedtls_cipher_definition_t *def;
@@ -163,9 +125,10 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher
return( NULL );
}
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
- int key_bitlen,
- const mbedtls_cipher_mode_t mode )
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
+ const mbedtls_cipher_id_t cipher_id,
+ int key_bitlen,
+ const mbedtls_cipher_mode_t mode )
{
const mbedtls_cipher_definition_t *def;
@@ -189,6 +152,29 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
if( ctx == NULL )
return;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ if( ctx->cipher_ctx != NULL )
+ {
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED )
+ {
+ /* xxx_free() doesn't allow to return failures. */
+ (void) psa_destroy_key( cipher_psa->slot );
+ }
+
+ mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) );
+ mbedtls_free( cipher_psa );
+ }
+
+ mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
+ return;
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_CMAC_C)
if( ctx->cmac_ctx )
{
@@ -204,7 +190,8 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
}
-int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
+int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info )
{
CIPHER_VALIDATE_RET( ctx != NULL );
if( cipher_info == NULL )
@@ -231,6 +218,38 @@ int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_in
return( 0 );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info,
+ size_t taglen )
+{
+ psa_algorithm_t alg;
+ mbedtls_cipher_context_psa *cipher_psa;
+
+ if( NULL == cipher_info || NULL == ctx )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* Check that the underlying cipher mode and cipher type are
+ * supported by the underlying PSA Crypto implementation. */
+ alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen );
+ if( alg == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
+
+ cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) );
+ if( cipher_psa == NULL )
+ return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+ cipher_psa->alg = alg;
+ ctx->cipher_ctx = cipher_psa;
+ ctx->cipher_info = cipher_info;
+ ctx->psa_enabled = 1;
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
const unsigned char *key,
int key_bitlen,
@@ -243,6 +262,64 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8;
+
+ psa_status_t status;
+ psa_key_type_t key_type;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* PSA Crypto API only accepts byte-aligned keys. */
+ if( key_bitlen % 8 != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* Don't allow keys to be set multiple times. */
+ if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ key_type = mbedtls_psa_translate_cipher_type(
+ ctx->cipher_info->type );
+ if( key_type == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ psa_set_key_type( &attributes, key_type );
+
+ /* Mbed TLS' cipher layer doesn't enforce the mode of operation
+ * (encrypt vs. decrypt): it is possible to setup a key for encryption
+ * and use it for AEAD decryption. Until tests relying on this
+ * are changed, allow any usage in PSA. */
+ psa_set_key_usage_flags( &attributes,
+ /* mbedtls_psa_translate_cipher_operation( operation ); */
+ PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
+ psa_set_key_algorithm( &attributes, cipher_psa->alg );
+
+ status = psa_import_key( &attributes, key, key_bytelen,
+ &cipher_psa->slot );
+ switch( status )
+ {
+ case PSA_SUCCESS:
+ break;
+ case PSA_ERROR_INSUFFICIENT_MEMORY:
+ return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+ case PSA_ERROR_NOT_SUPPORTED:
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ default:
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+ }
+ /* Indicate that we own the key slot and need to
+ * destroy it in mbedtls_cipher_free(). */
+ cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
+
+ ctx->key_bitlen = key_bitlen;
+ ctx->operation = operation;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
(int) ctx->cipher_info->key_bitlen != key_bitlen )
{
@@ -281,6 +358,15 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* avoid buffer overflow in ctx->iv */
if( iv_len > MBEDTLS_MAX_IV_LENGTH )
@@ -324,6 +410,15 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* We don't support resetting PSA-based
+ * cipher contexts, yet. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
ctx->unprocessed_len = 0;
return( 0 );
@@ -338,6 +433,16 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
@@ -374,7 +479,7 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
size_t ilen, unsigned char *output, size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t block_size;
CIPHER_VALIDATE_RET( ctx != NULL );
@@ -384,6 +489,16 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
*olen = 0;
block_size = mbedtls_cipher_get_block_size( ctx );
if ( 0 == block_size )
@@ -787,6 +902,16 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
*olen = 0;
if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
@@ -879,6 +1004,19 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto knows about CBC padding
+ * schemes, we currently don't make them
+ * accessible through the cipher layer. */
+ if( mode != MBEDTLS_PADDING_NONE )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
switch( mode )
{
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
@@ -930,6 +1068,16 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
if( MBEDTLS_ENCRYPT != ctx->operation )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
@@ -943,8 +1091,8 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
if ( tag_len != 16U )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- tag ) );
+ return( mbedtls_chachapoly_finish(
+ (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) );
}
#endif
@@ -955,7 +1103,7 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len )
{
unsigned char check_tag[16];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
@@ -967,6 +1115,16 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/* Status to return on a non-authenticated algorithm. It would make sense
* to return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT or perhaps
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, but at the time I write this our
@@ -979,14 +1137,15 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
if( tag_len > sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
- check_tag, tag_len ) ) )
+ if( 0 != ( ret = mbedtls_gcm_finish(
+ (mbedtls_gcm_context *) ctx->cipher_ctx,
+ check_tag, tag_len ) ) )
{
return( ret );
}
/* Check the tag in "constant-time" */
- if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+ if( mbedtls_ct_memcmp( tag, check_tag, tag_len ) != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
goto exit;
@@ -1001,15 +1160,15 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
if ( tag_len != sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- check_tag );
+ ret = mbedtls_chachapoly_finish(
+ (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag );
if ( ret != 0 )
{
return( ret );
}
/* Check the tag in "constant-time" */
- if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+ if( mbedtls_ct_memcmp( tag, check_tag, tag_len ) != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
goto exit;
@@ -1031,7 +1190,7 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t finish_olen;
CIPHER_VALIDATE_RET( ctx != NULL );
@@ -1040,16 +1199,79 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
CIPHER_VALIDATE_RET( output != NULL );
CIPHER_VALIDATE_RET( olen != NULL );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+ psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
+ size_t part_len;
+
+ if( ctx->operation == MBEDTLS_DECRYPT )
+ {
+ status = psa_cipher_decrypt_setup( &cipher_op,
+ cipher_psa->slot,
+ cipher_psa->alg );
+ }
+ else if( ctx->operation == MBEDTLS_ENCRYPT )
+ {
+ status = psa_cipher_encrypt_setup( &cipher_op,
+ cipher_psa->slot,
+ cipher_psa->alg );
+ }
+ else
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* In the following, we can immediately return on an error,
+ * because the PSA Crypto API guarantees that cipher operations
+ * are terminated by unsuccessful calls to psa_cipher_update(),
+ * and by any call to psa_cipher_finish(). */
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ if( ctx->cipher_info->mode != MBEDTLS_MODE_ECB )
+ {
+ status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+ }
+
+ status = psa_cipher_update( &cipher_op,
+ input, ilen,
+ output, ilen, olen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ status = psa_cipher_finish( &cipher_op,
+ output + *olen, ilen - *olen,
+ &part_len );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ *olen += part_len;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
return( ret );
if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
return( ret );
- if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
+ if( ( ret = mbedtls_cipher_update( ctx, input, ilen,
+ output, olen ) ) != 0 )
return( ret );
- if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
+ if( ( ret = mbedtls_cipher_finish( ctx, output + *olen,
+ &finish_olen ) ) != 0 )
return( ret );
*olen += finish_olen;
@@ -1059,30 +1281,55 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
/*
- * Packet-oriented encryption for AEAD modes
+ * Packet-oriented encryption for AEAD modes: internal function shared by
+ * mbedtls_cipher_auth_encrypt() and mbedtls_cipher_auth_encrypt_ext().
*/
-int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+static int mbedtls_cipher_aead_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len )
{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+
+ /* PSA Crypto API always writes the authentication tag
+ * at the end of the encrypted message. */
+ if( output == NULL || tag != output + ilen )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ status = psa_aead_encrypt( cipher_psa->slot,
+ cipher_psa->alg,
+ iv, iv_len,
+ ad, ad_len,
+ input, ilen,
+ output, ilen + tag_len, olen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ *olen -= tag_len;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
*olen = ilen;
- return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen,
- iv, iv_len, ad, ad_len, input, output,
- tag_len, tag ) );
+ return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
+ ilen, iv, iv_len, ad, ad_len,
+ input, output, tag_len, tag ) );
}
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CCM_C)
@@ -1114,27 +1361,53 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
}
/*
- * Packet-oriented decryption for AEAD modes
+ * Packet-oriented encryption for AEAD modes: internal function shared by
+ * mbedtls_cipher_auth_encrypt() and mbedtls_cipher_auth_encrypt_ext().
*/
-int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+static int mbedtls_cipher_aead_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len )
{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+
+ /* PSA Crypto API always writes the authentication tag
+ * at the end of the encrypted message. */
+ if( input == NULL || tag != input + ilen )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ status = psa_aead_decrypt( cipher_psa->slot,
+ cipher_psa->alg,
+ iv, iv_len,
+ ad, ad_len,
+ input, ilen + tag_len,
+ output, ilen, olen );
+ if( status == PSA_ERROR_INVALID_SIGNATURE )
+ return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+ else if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
*olen = ilen;
ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
@@ -1150,7 +1423,7 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CCM_C)
if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
*olen = ilen;
ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
@@ -1166,7 +1439,7 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* ChachaPoly has fixed length nonce and MAC (tag) */
if ( ( iv_len != ctx->cipher_info->iv_size ) ||
@@ -1188,6 +1461,166 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+/*
+ * Packet-oriented encryption for AEAD modes: public legacy function.
+ */
+int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+ return( mbedtls_cipher_aead_encrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ tag, tag_len ) );
+}
+
+/*
+ * Packet-oriented decryption for AEAD modes: public legacy function.
+ */
+int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ const unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+ return( mbedtls_cipher_aead_decrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ tag, tag_len ) );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
+/*
+ * Packet-oriented encryption for AEAD/NIST_KW: public function.
+ */
+int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+
+#if defined(MBEDTLS_NIST_KW_C)
+ if(
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ctx->psa_enabled == 0 &&
+#endif
+ ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) )
+ {
+ mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
+ MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
+
+ /* There is no iv, tag or ad associated with KW and KWP,
+ * so these length should be 0 as documented. */
+ if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ (void) iv;
+ (void) ad;
+
+ return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen,
+ output, olen, output_len ) );
+ }
+#endif /* MBEDTLS_NIST_KW_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+ /* AEAD case: check length before passing on to shared function */
+ if( output_len < ilen + tag_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ int ret = mbedtls_cipher_aead_encrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ output + ilen, tag_len );
+ *olen += tag_len;
+ return( ret );
+#else
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+}
+
+/*
+ * Packet-oriented decryption for AEAD/NIST_KW: public function.
+ */
+int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output_len == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+
+#if defined(MBEDTLS_NIST_KW_C)
+ if(
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ctx->psa_enabled == 0 &&
+#endif
+ ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) )
+ {
+ mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
+ MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
+
+ /* There is no iv, tag or ad associated with KW and KWP,
+ * so these length should be 0 as documented. */
+ if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ (void) iv;
+ (void) ad;
+
+ return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen,
+ output, olen, output_len ) );
+ }
+#endif /* MBEDTLS_NIST_KW_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+ /* AEAD case: check length before passing on to shared function */
+ if( ilen < tag_len || output_len < ilen - tag_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ return( mbedtls_cipher_aead_decrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen - tag_len, output, olen,
+ input + ilen - tag_len, tag_len ) );
+#else
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+}
+#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
+
#endif /* MBEDTLS_CIPHER_C */
diff --git a/thirdparty/mbedtls/library/cipher_wrap.c b/thirdparty/mbedtls/library/cipher_wrap.c
index 5973ca6ba2..57eb3cb67f 100644
--- a/thirdparty/mbedtls/library/cipher_wrap.c
+++ b/thirdparty/mbedtls/library/cipher_wrap.c
@@ -6,13 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,38 +19,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher_internal.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
@@ -98,6 +68,10 @@
#include "mbedtls/ccm.h"
#endif
+#if defined(MBEDTLS_NIST_KW_C)
+#include "mbedtls/nist_kw.h"
+#endif
+
#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
#include <string.h>
#endif
@@ -1937,7 +1911,7 @@ static int chacha20_stream_wrap( void *ctx, size_t length,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_chacha20_update( ctx, length, input, output );
if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
@@ -2144,6 +2118,131 @@ static const mbedtls_cipher_info_t null_cipher_info = {
};
#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */
+#if defined(MBEDTLS_NIST_KW_C)
+static void *kw_ctx_alloc( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_nist_kw_context ) );
+
+ if( ctx != NULL )
+ mbedtls_nist_kw_init( (mbedtls_nist_kw_context *) ctx );
+
+ return( ctx );
+}
+
+static void kw_ctx_free( void *ctx )
+{
+ mbedtls_nist_kw_free( ctx );
+ mbedtls_free( ctx );
+}
+
+static int kw_aes_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
+ MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1 );
+}
+
+static int kw_aes_setkey_unwrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
+ MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0 );
+}
+
+static const mbedtls_cipher_base_t kw_aes_info = {
+ MBEDTLS_CIPHER_ID_AES,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ kw_aes_setkey_wrap,
+ kw_aes_setkey_unwrap,
+ kw_ctx_alloc,
+ kw_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aes_128_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_128_KW,
+ MBEDTLS_MODE_KW,
+ 128,
+ "AES-128-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_192_KW,
+ MBEDTLS_MODE_KW,
+ 192,
+ "AES-192-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_256_KW,
+ MBEDTLS_MODE_KW,
+ 256,
+ "AES-256-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_128_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_128_KWP,
+ MBEDTLS_MODE_KWP,
+ 128,
+ "AES-128-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_192_KWP,
+ MBEDTLS_MODE_KWP,
+ 192,
+ "AES-192-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_256_KWP,
+ MBEDTLS_MODE_KWP,
+ 256,
+ "AES-256-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+#endif /* MBEDTLS_NIST_KW_C */
+
const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{
#if defined(MBEDTLS_AES_C)
@@ -2284,6 +2383,15 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{ MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info },
#endif
+#if defined(MBEDTLS_NIST_KW_C)
+ { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info },
+ { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info },
+ { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info },
+#endif
+
#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
{ MBEDTLS_CIPHER_NULL, &null_cipher_info },
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
@@ -2291,7 +2399,8 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{ MBEDTLS_CIPHER_NONE, NULL }
};
-#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0]
+#define NUM_CIPHERS ( sizeof(mbedtls_cipher_definitions) / \
+ sizeof(mbedtls_cipher_definitions[0]) )
int mbedtls_cipher_supported[NUM_CIPHERS];
#endif /* MBEDTLS_CIPHER_C */
diff --git a/thirdparty/mbedtls/library/cmac.c b/thirdparty/mbedtls/library/cmac.c
index 409f67958e..3cc49d10cc 100644
--- a/thirdparty/mbedtls/library/cmac.c
+++ b/thirdparty/mbedtls/library/cmac.c
@@ -4,13 +4,7 @@
* \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,27 +17,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -65,32 +38,17 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CMAC_C)
#include "mbedtls/cmac.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform.h"
#include <string.h>
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#if defined(MBEDTLS_SELF_TEST)
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_SELF_TEST */
-#endif /* MBEDTLS_PLATFORM_C */
-
#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
/*
@@ -161,7 +119,7 @@ static int cmac_multiply_by_u( unsigned char *output,
static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
unsigned char* K1, unsigned char* K2 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
size_t olen, block_size;
@@ -340,7 +298,7 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen, block_size;
if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
@@ -418,7 +376,7 @@ int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
unsigned char *output )
{
mbedtls_cipher_context_t ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
@@ -452,7 +410,7 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
const unsigned char *input, size_t in_len,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
@@ -808,7 +766,7 @@ static int cmac_test_subkeys( int verbose,
for( i = 0; i < num_tests; i++ )
{
if( verbose != 0 )
- mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
+ mbedtls_printf( " %s CMAC subkey #%d: ", testname, i + 1 );
mbedtls_cipher_init( &ctx );
@@ -823,6 +781,18 @@ static int cmac_test_subkeys( int verbose,
if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
MBEDTLS_ENCRYPT ) ) != 0 )
{
+ /* When CMAC is implemented by an alternative implementation, or
+ * the underlying primitive itself is implemented alternatively,
+ * AES-192 may be unavailable. This should not cause the selftest
+ * function to fail. */
+ if( ( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
+ ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) &&
+ cipher_type == MBEDTLS_CIPHER_AES_192_ECB ) {
+ if( verbose != 0 )
+ mbedtls_printf( "skipped\n" );
+ goto next_test;
+ }
+
if( verbose != 0 )
mbedtls_printf( "test execution failed\n" );
@@ -850,6 +820,7 @@ static int cmac_test_subkeys( int verbose,
if( verbose != 0 )
mbedtls_printf( "passed\n" );
+next_test:
mbedtls_cipher_free( &ctx );
}
@@ -889,11 +860,24 @@ static int cmac_test_wth_cipher( int verbose,
for( i = 0; i < num_tests; i++ )
{
if( verbose != 0 )
- mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
+ mbedtls_printf( " %s CMAC #%d: ", testname, i + 1 );
if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
message_lengths[i], output ) ) != 0 )
{
+ /* When CMAC is implemented by an alternative implementation, or
+ * the underlying primitive itself is implemented alternatively,
+ * AES-192 and/or 3DES may be unavailable. This should not cause
+ * the selftest function to fail. */
+ if( ( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
+ ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) &&
+ ( cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
+ cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB ) ) {
+ if( verbose != 0 )
+ mbedtls_printf( "skipped\n" );
+ continue;
+ }
+
if( verbose != 0 )
mbedtls_printf( "failed\n" );
goto exit;
@@ -919,12 +903,12 @@ exit:
static int test_aes128_cmac_prf( int verbose )
{
int i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
for( i = 0; i < NB_PRF_TESTS; i++ )
{
- mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
+ mbedtls_printf( " AES CMAC 128 PRF #%d: ", i );
ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
if( ret != 0 ||
memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
@@ -946,7 +930,7 @@ static int test_aes128_cmac_prf( int verbose )
int mbedtls_cmac_self_test( int verbose )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_AES_C)
/* AES-128 */
diff --git a/thirdparty/mbedtls/library/common.h b/thirdparty/mbedtls/library/common.h
new file mode 100644
index 0000000000..c06472418d
--- /dev/null
+++ b/thirdparty/mbedtls/library/common.h
@@ -0,0 +1,305 @@
+/**
+ * \file common.h
+ *
+ * \brief Utility macros for internal use in the library
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_LIBRARY_COMMON_H
+#define MBEDTLS_LIBRARY_COMMON_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#else
+#include "mbedtls/config.h"
+#endif
+
+#include <stdint.h>
+
+/** Helper to define a function as static except when building invasive tests.
+ *
+ * If a function is only used inside its own source file and should be
+ * declared `static` to allow the compiler to optimize for code size,
+ * but that function has unit tests, define it with
+ * ```
+ * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
+ * ```
+ * and declare it in a header in the `library/` directory with
+ * ```
+ * #if defined(MBEDTLS_TEST_HOOKS)
+ * int mbedtls_foo(...);
+ * #endif
+ * ```
+ */
+#if defined(MBEDTLS_TEST_HOOKS)
+#define MBEDTLS_STATIC_TESTABLE
+#else
+#define MBEDTLS_STATIC_TESTABLE static
+#endif
+
+/** Byte Reading Macros
+ *
+ * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
+ * byte from x, where byte 0 is the least significant byte.
+ */
+#define MBEDTLS_BYTE_0( x ) ( (uint8_t) ( ( x ) & 0xff ) )
+#define MBEDTLS_BYTE_1( x ) ( (uint8_t) ( ( ( x ) >> 8 ) & 0xff ) )
+#define MBEDTLS_BYTE_2( x ) ( (uint8_t) ( ( ( x ) >> 16 ) & 0xff ) )
+#define MBEDTLS_BYTE_3( x ) ( (uint8_t) ( ( ( x ) >> 24 ) & 0xff ) )
+#define MBEDTLS_BYTE_4( x ) ( (uint8_t) ( ( ( x ) >> 32 ) & 0xff ) )
+#define MBEDTLS_BYTE_5( x ) ( (uint8_t) ( ( ( x ) >> 40 ) & 0xff ) )
+#define MBEDTLS_BYTE_6( x ) ( (uint8_t) ( ( ( x ) >> 48 ) & 0xff ) )
+#define MBEDTLS_BYTE_7( x ) ( (uint8_t) ( ( ( x ) >> 56 ) & 0xff ) )
+
+/**
+ * Get the unsigned 32 bits integer corresponding to four bytes in
+ * big-endian order (MSB first).
+ *
+ * \param data Base address of the memory to get the four bytes from.
+ * \param offset Offset from \p base of the first and most significant
+ * byte of the four bytes to build the 32 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT32_BE
+#define MBEDTLS_GET_UINT32_BE( data , offset ) \
+ ( \
+ ( (uint32_t) ( data )[( offset ) ] << 24 ) \
+ | ( (uint32_t) ( data )[( offset ) + 1] << 16 ) \
+ | ( (uint32_t) ( data )[( offset ) + 2] << 8 ) \
+ | ( (uint32_t) ( data )[( offset ) + 3] ) \
+ )
+#endif
+
+/**
+ * Put in memory a 32 bits unsigned integer in big-endian order.
+ *
+ * \param n 32 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 32
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the most significant
+ * byte of the 32 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT32_BE
+#define MBEDTLS_PUT_UINT32_BE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_3( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_2( n ); \
+ ( data )[( offset ) + 2] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 3] = MBEDTLS_BYTE_0( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 32 bits integer corresponding to four bytes in
+ * little-endian order (LSB first).
+ *
+ * \param data Base address of the memory to get the four bytes from.
+ * \param offset Offset from \p base of the first and least significant
+ * byte of the four bytes to build the 32 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT32_LE
+#define MBEDTLS_GET_UINT32_LE( data, offset ) \
+ ( \
+ ( (uint32_t) ( data )[( offset ) ] ) \
+ | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \
+ | ( (uint32_t) ( data )[( offset ) + 2] << 16 ) \
+ | ( (uint32_t) ( data )[( offset ) + 3] << 24 ) \
+ )
+#endif
+
+/**
+ * Put in memory a 32 bits unsigned integer in little-endian order.
+ *
+ * \param n 32 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 32
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the least significant
+ * byte of the 32 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT32_LE
+#define MBEDTLS_PUT_UINT32_LE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \
+ ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 16 bits integer corresponding to two bytes in
+ * little-endian order (LSB first).
+ *
+ * \param data Base address of the memory to get the two bytes from.
+ * \param offset Offset from \p base of the first and least significant
+ * byte of the two bytes to build the 16 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT16_LE
+#define MBEDTLS_GET_UINT16_LE( data, offset ) \
+ ( \
+ ( (uint16_t) ( data )[( offset ) ] ) \
+ | ( (uint16_t) ( data )[( offset ) + 1] << 8 ) \
+ )
+#endif
+
+/**
+ * Put in memory a 16 bits unsigned integer in little-endian order.
+ *
+ * \param n 16 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 16
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the least significant
+ * byte of the 16 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT16_LE
+#define MBEDTLS_PUT_UINT16_LE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 16 bits integer corresponding to two bytes in
+ * big-endian order (MSB first).
+ *
+ * \param data Base address of the memory to get the two bytes from.
+ * \param offset Offset from \p base of the first and most significant
+ * byte of the two bytes to build the 16 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT16_BE
+#define MBEDTLS_GET_UINT16_BE( data, offset ) \
+ ( \
+ ( (uint16_t) ( data )[( offset ) ] << 8 ) \
+ | ( (uint16_t) ( data )[( offset ) + 1] ) \
+ )
+#endif
+
+/**
+ * Put in memory a 16 bits unsigned integer in big-endian order.
+ *
+ * \param n 16 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 16
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the most significant
+ * byte of the 16 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT16_BE
+#define MBEDTLS_PUT_UINT16_BE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_0( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 64 bits integer corresponding to eight bytes in
+ * big-endian order (MSB first).
+ *
+ * \param data Base address of the memory to get the eight bytes from.
+ * \param offset Offset from \p base of the first and most significant
+ * byte of the eight bytes to build the 64 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT64_BE
+#define MBEDTLS_GET_UINT64_BE( data, offset ) \
+ ( \
+ ( (uint64_t) ( data )[( offset ) ] << 56 ) \
+ | ( (uint64_t) ( data )[( offset ) + 1] << 48 ) \
+ | ( (uint64_t) ( data )[( offset ) + 2] << 40 ) \
+ | ( (uint64_t) ( data )[( offset ) + 3] << 32 ) \
+ | ( (uint64_t) ( data )[( offset ) + 4] << 24 ) \
+ | ( (uint64_t) ( data )[( offset ) + 5] << 16 ) \
+ | ( (uint64_t) ( data )[( offset ) + 6] << 8 ) \
+ | ( (uint64_t) ( data )[( offset ) + 7] ) \
+ )
+#endif
+
+/**
+ * Put in memory a 64 bits unsigned integer in big-endian order.
+ *
+ * \param n 64 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 64
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the most significant
+ * byte of the 64 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT64_BE
+#define MBEDTLS_PUT_UINT64_BE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_7( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_6( n ); \
+ ( data )[( offset ) + 2] = MBEDTLS_BYTE_5( n ); \
+ ( data )[( offset ) + 3] = MBEDTLS_BYTE_4( n ); \
+ ( data )[( offset ) + 4] = MBEDTLS_BYTE_3( n ); \
+ ( data )[( offset ) + 5] = MBEDTLS_BYTE_2( n ); \
+ ( data )[( offset ) + 6] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 7] = MBEDTLS_BYTE_0( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 64 bits integer corresponding to eight bytes in
+ * little-endian order (LSB first).
+ *
+ * \param data Base address of the memory to get the eight bytes from.
+ * \param offset Offset from \p base of the first and least significant
+ * byte of the eight bytes to build the 64 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT64_LE
+#define MBEDTLS_GET_UINT64_LE( data, offset ) \
+ ( \
+ ( (uint64_t) ( data )[( offset ) + 7] << 56 ) \
+ | ( (uint64_t) ( data )[( offset ) + 6] << 48 ) \
+ | ( (uint64_t) ( data )[( offset ) + 5] << 40 ) \
+ | ( (uint64_t) ( data )[( offset ) + 4] << 32 ) \
+ | ( (uint64_t) ( data )[( offset ) + 3] << 24 ) \
+ | ( (uint64_t) ( data )[( offset ) + 2] << 16 ) \
+ | ( (uint64_t) ( data )[( offset ) + 1] << 8 ) \
+ | ( (uint64_t) ( data )[( offset ) ] ) \
+ )
+#endif
+
+/**
+ * Put in memory a 64 bits unsigned integer in little-endian order.
+ *
+ * \param n 64 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 64
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the least significant
+ * byte of the 64 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT64_LE
+#define MBEDTLS_PUT_UINT64_LE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \
+ ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n ); \
+ ( data )[( offset ) + 4] = MBEDTLS_BYTE_4( n ); \
+ ( data )[( offset ) + 5] = MBEDTLS_BYTE_5( n ); \
+ ( data )[( offset ) + 6] = MBEDTLS_BYTE_6( n ); \
+ ( data )[( offset ) + 7] = MBEDTLS_BYTE_7( n ); \
+}
+#endif
+
+#endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/thirdparty/mbedtls/library/constant_time.c b/thirdparty/mbedtls/library/constant_time.c
new file mode 100644
index 0000000000..18f1b20daa
--- /dev/null
+++ b/thirdparty/mbedtls/library/constant_time.c
@@ -0,0 +1,819 @@
+/**
+ * Constant-time functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /*
+ * The following functions are implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+
+#include "common.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "mbedtls/ssl_internal.h"
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+
+#if defined(MBEDTLS_BASE64_C)
+#include "constant_time_invasive.h"
+#endif
+
+#include <string.h>
+
+int mbedtls_ct_memcmp( const void *a,
+ const void *b,
+ size_t n )
+{
+ size_t i;
+ volatile const unsigned char *A = (volatile const unsigned char *) a;
+ volatile const unsigned char *B = (volatile const unsigned char *) b;
+ volatile unsigned char diff = 0;
+
+ for( i = 0; i < n; i++ )
+ {
+ /* Read volatile data in order before computing diff.
+ * This avoids IAR compiler warning:
+ * 'the order of volatile accesses is undefined ..' */
+ unsigned char x = A[i], y = B[i];
+ diff |= x ^ y;
+ }
+
+ return( (int)diff );
+}
+
+unsigned mbedtls_ct_uint_mask( 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
+}
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+size_t mbedtls_ct_size_mask( size_t value )
+{
+ /* 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
+ return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask( mbedtls_mpi_uint 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
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Constant-flow mask generation for "less than" comparison:
+ * - if \p x < \p y, return all-bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return All-bits-one if \p x is less than \p y, otherwise zero.
+ */
+static size_t mbedtls_ct_size_mask_lt( size_t x,
+ size_t y )
+{
+ /* This has the most significant bit set if and only if x < y */
+ const size_t sub = x - y;
+
+ /* sub1 = (x < y) ? 1 : 0 */
+ const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 );
+
+ /* mask = (x < y) ? 0xff... : 0x00... */
+ const size_t mask = mbedtls_ct_size_mask( sub1 );
+
+ return( mask );
+}
+
+size_t mbedtls_ct_size_mask_ge( size_t x,
+ size_t y )
+{
+ return( ~mbedtls_ct_size_mask_lt( x, y ) );
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BASE64_C)
+
+/* Return 0xff if low <= c <= high, 0 otherwise.
+ *
+ * Constant flow with respect to c.
+ */
+MBEDTLS_STATIC_TESTABLE
+unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low,
+ unsigned char high,
+ unsigned char c )
+{
+ /* low_mask is: 0 if low <= c, 0x...ff if low > c */
+ unsigned low_mask = ( (unsigned) c - low ) >> 8;
+ /* high_mask is: 0 if c <= high, 0x...ff if c > high */
+ unsigned high_mask = ( (unsigned) high - c ) >> 8;
+ return( ~( low_mask | high_mask ) & 0xff );
+}
+
+#endif /* MBEDTLS_BASE64_C */
+
+unsigned mbedtls_ct_size_bool_eq( size_t x,
+ size_t y )
+{
+ /* diff = 0 if x == y, non-zero otherwise */
+ const size_t diff = x ^ y;
+
+ /* 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
+
+ /* diff_msb's most significant bit is equal to x != y */
+ const size_t diff_msb = ( diff | (size_t) -diff );
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+ /* diff1 = (x != y) ? 1 : 0 */
+ const unsigned diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
+
+ return( 1 ^ diff1 );
+}
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** Constant-flow "greater than" comparison:
+ * return x > y
+ *
+ * This is equivalent to \p x > \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return 1 if \p x greater than \p y, otherwise 0.
+ */
+static unsigned mbedtls_ct_size_gt( size_t x,
+ size_t y )
+{
+ /* Return the sign bit (1 for negative) of (y - x). */
+ return( ( y - x ) >> ( sizeof( size_t ) * 8 - 1 ) );
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
+ const mbedtls_mpi_uint y )
+{
+ mbedtls_mpi_uint ret;
+ mbedtls_mpi_uint cond;
+
+ /*
+ * Check if the most significant bits (MSB) of the operands are different.
+ */
+ cond = ( x ^ y );
+ /*
+ * If the MSB are the same then the difference x-y will be negative (and
+ * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
+ */
+ ret = ( x - y ) & ~cond;
+ /*
+ * If the MSB are different, then the operand with the MSB of 1 is the
+ * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
+ * the MSB of y is 0.)
+ */
+ ret |= y & cond;
+
+
+ ret = ret >> ( sizeof( mbedtls_mpi_uint ) * 8 - 1 );
+
+ return (unsigned) ret;
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+unsigned mbedtls_ct_uint_if( unsigned condition,
+ unsigned if1,
+ unsigned if0 )
+{
+ unsigned mask = mbedtls_ct_uint_mask( condition );
+ return( ( mask & if1 ) | (~mask & if0 ) );
+}
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Select between two sign values without branches.
+ *
+ * This is functionally equivalent to `condition ? if1 : if0` but uses only bit
+ * operations in order to avoid branches.
+ *
+ * \note if1 and if0 must be either 1 or -1, otherwise the result
+ * is undefined.
+ *
+ * \param condition Condition to test.
+ * \param if1 The first sign; must be either +1 or -1.
+ * \param if0 The second sign; must be either +1 or -1.
+ *
+ * \return \c if1 if \p condition is nonzero, otherwise \c if0.
+ * */
+static int mbedtls_ct_cond_select_sign( unsigned char condition,
+ int if1,
+ int if0 )
+{
+ /* In order to avoid questions about what we can reasonably assume about
+ * the representations of signed integers, move everything to unsigned
+ * by taking advantage of the fact that if1 and if0 are either +1 or -1. */
+ unsigned uif1 = if1 + 1;
+ unsigned uif0 = if0 + 1;
+
+ /* condition was 0 or 1, mask is 0 or 2 as are uif1 and uif0 */
+ const unsigned mask = condition << 1;
+
+ /* select uif1 or uif0 */
+ unsigned ur = ( uif0 & ~mask ) | ( uif1 & mask );
+
+ /* ur is now 0 or 2, convert back to -1 or +1 */
+ return( (int) ur - 1 );
+}
+
+void mbedtls_ct_mpi_uint_cond_assign( size_t n,
+ mbedtls_mpi_uint *dest,
+ const mbedtls_mpi_uint *src,
+ unsigned char condition )
+{
+ size_t i;
+
+ /* 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
+
+ /* all-bits 1 if condition is 1, all-bits 0 if condition is 0 */
+ const mbedtls_mpi_uint mask = -condition;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+ for( i = 0; i < n; i++ )
+ dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_BASE64_C)
+
+unsigned char mbedtls_ct_base64_enc_char( unsigned char value )
+{
+ unsigned char digit = 0;
+ /* For each range of values, if value is in that range, mask digit with
+ * the corresponding value. Since value can only be in a single range,
+ * only at most one masking will change digit. */
+ digit |= mbedtls_ct_uchar_mask_of_range( 0, 25, value ) & ( 'A' + value );
+ digit |= mbedtls_ct_uchar_mask_of_range( 26, 51, value ) & ( 'a' + value - 26 );
+ digit |= mbedtls_ct_uchar_mask_of_range( 52, 61, value ) & ( '0' + value - 52 );
+ digit |= mbedtls_ct_uchar_mask_of_range( 62, 62, value ) & '+';
+ digit |= mbedtls_ct_uchar_mask_of_range( 63, 63, value ) & '/';
+ return( digit );
+}
+
+signed char mbedtls_ct_base64_dec_value( unsigned char c )
+{
+ unsigned char val = 0;
+ /* For each range of digits, if c is in that range, mask val with
+ * the corresponding value. Since c can only be in a single range,
+ * only at most one masking will change val. Set val to one plus
+ * the desired value so that it stays 0 if c is in none of the ranges. */
+ val |= mbedtls_ct_uchar_mask_of_range( 'A', 'Z', c ) & ( c - 'A' + 0 + 1 );
+ val |= mbedtls_ct_uchar_mask_of_range( 'a', 'z', c ) & ( c - 'a' + 26 + 1 );
+ val |= mbedtls_ct_uchar_mask_of_range( '0', '9', c ) & ( c - '0' + 52 + 1 );
+ val |= mbedtls_ct_uchar_mask_of_range( '+', '+', c ) & ( c - '+' + 62 + 1 );
+ val |= mbedtls_ct_uchar_mask_of_range( '/', '/', c ) & ( c - '/' + 63 + 1 );
+ /* At this point, val is 0 if c is an invalid digit and v+1 if c is
+ * a digit with the value v. */
+ return( val - 1 );
+}
+
+#endif /* MBEDTLS_BASE64_C */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** Shift some data towards the left inside a buffer.
+ *
+ * `mbedtls_ct_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 mbedtls_ct_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 = mbedtls_ct_size_gt( 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] = mbedtls_ct_uint_if( no_op, current, next );
+ }
+ buf[total-1] = mbedtls_ct_uint_if( no_op, buf[total-1], 0 );
+ }
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
+ const unsigned char *src,
+ size_t len,
+ size_t c1,
+ size_t c2 )
+{
+ /* mask = c1 == c2 ? 0xff : 0x00 */
+ const size_t equal = mbedtls_ct_size_bool_eq( c1, c2 );
+ const unsigned char mask = (unsigned char) mbedtls_ct_size_mask( equal );
+
+ /* dest[i] = c1 == c2 ? src[i] : dest[i] */
+ for( size_t i = 0; i < len; i++ )
+ dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
+}
+
+void mbedtls_ct_memcpy_offset( unsigned char *dest,
+ const unsigned char *src,
+ size_t offset,
+ size_t offset_min,
+ size_t offset_max,
+ size_t len )
+{
+ size_t offsetval;
+
+ for( offsetval = offset_min; offsetval <= offset_max; offsetval++ )
+ {
+ mbedtls_ct_memcpy_if_eq( dest, src + offsetval, len,
+ offsetval, offset );
+ }
+}
+
+int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
+ const unsigned char *add_data,
+ size_t add_data_len,
+ const unsigned char *data,
+ size_t data_len_secret,
+ size_t min_data_len,
+ size_t max_data_len,
+ unsigned char *output )
+{
+ /*
+ * This function breaks the HMAC abstraction and uses the md_clone()
+ * extension to the MD API in order to get constant-flow behaviour.
+ *
+ * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
+ * concatenation, and okey/ikey are the XOR of the key with some fixed bit
+ * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
+ *
+ * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
+ * minlen, then cloning the context, and for each byte up to maxlen
+ * finishing up the hash computation, keeping only the correct result.
+ *
+ * Then we only need to compute HASH(okey + inner_hash) and we're done.
+ */
+ const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info );
+ /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5,
+ * all of which have the same block size except SHA-384. */
+ const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
+ const unsigned char * const ikey = ctx->hmac_ctx;
+ const unsigned char * const okey = ikey + block_size;
+ const size_t hash_size = mbedtls_md_get_size( ctx->md_info );
+
+ unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
+ mbedtls_md_context_t aux;
+ size_t offset;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ mbedtls_md_init( &aux );
+
+#define MD_CHK( func_call ) \
+ do { \
+ ret = (func_call); \
+ if( ret != 0 ) \
+ goto cleanup; \
+ } while( 0 )
+
+ MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) );
+
+ /* After hmac_start() of hmac_reset(), ikey has already been hashed,
+ * so we can start directly with the message */
+ MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
+ MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
+
+ /* For each possible length, compute the hash up to that point */
+ for( offset = min_data_len; offset <= max_data_len; offset++ )
+ {
+ MD_CHK( mbedtls_md_clone( &aux, ctx ) );
+ MD_CHK( mbedtls_md_finish( &aux, aux_out ) );
+ /* Keep only the correct inner_hash in the output buffer */
+ mbedtls_ct_memcpy_if_eq( output, aux_out, hash_size,
+ offset, data_len_secret );
+
+ if( offset < max_data_len )
+ MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
+ }
+
+ /* The context needs to finish() before it starts() again */
+ MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
+
+ /* Now compute HASH(okey + inner_hash) */
+ MD_CHK( mbedtls_md_starts( ctx ) );
+ MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
+ MD_CHK( mbedtls_md_update( ctx, output, hash_size ) );
+ MD_CHK( mbedtls_md_finish( ctx, output ) );
+
+ /* Done, get ready for next time */
+ MD_CHK( mbedtls_md_hmac_reset( ctx ) );
+
+#undef MD_CHK
+
+cleanup:
+ mbedtls_md_free( &aux );
+ return( ret );
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#define MPI_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+
+/*
+ * Conditionally assign X = Y, without leaking information
+ * about whether the assignment was made or not.
+ * (Leaking information about the respective sizes of X and Y is ok however.)
+ */
+int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X,
+ const mbedtls_mpi *Y,
+ unsigned char assign )
+{
+ int ret = 0;
+ size_t i;
+ mbedtls_mpi_uint limb_mask;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
+
+ /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
+ limb_mask = mbedtls_ct_mpi_uint_mask( assign );;
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+
+ X->s = mbedtls_ct_cond_select_sign( assign, Y->s, X->s );
+
+ mbedtls_ct_mpi_uint_cond_assign( Y->n, X->p, Y->p, assign );
+
+ for( i = Y->n; i < X->n; i++ )
+ X->p[i] &= ~limb_mask;
+
+cleanup:
+ return( ret );
+}
+
+/*
+ * Conditionally swap X and Y, without leaking information
+ * about whether the swap was made or not.
+ * Here it is not ok to simply swap the pointers, which whould lead to
+ * different memory access patterns when X and Y are used afterwards.
+ */
+int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
+ mbedtls_mpi *Y,
+ unsigned char swap )
+{
+ int ret, s;
+ size_t i;
+ mbedtls_mpi_uint limb_mask;
+ mbedtls_mpi_uint tmp;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
+
+ if( X == Y )
+ return( 0 );
+
+ /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
+ limb_mask = mbedtls_ct_mpi_uint_mask( swap );
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
+
+ s = X->s;
+ X->s = mbedtls_ct_cond_select_sign( swap, Y->s, X->s );
+ Y->s = mbedtls_ct_cond_select_sign( swap, s, Y->s );
+
+
+ for( i = 0; i < X->n; i++ )
+ {
+ tmp = X->p[i];
+ X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
+ Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
+ }
+
+cleanup:
+ return( ret );
+}
+
+/*
+ * Compare signed values in constant time
+ */
+int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X,
+ const mbedtls_mpi *Y,
+ unsigned *ret )
+{
+ size_t i;
+ /* The value of any of these variables is either 0 or 1 at all times. */
+ unsigned cond, done, X_is_negative, Y_is_negative;
+
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
+ MPI_VALIDATE_RET( ret != NULL );
+
+ if( X->n != Y->n )
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+
+ /*
+ * Set sign_N to 1 if N >= 0, 0 if N < 0.
+ * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
+ */
+ X_is_negative = ( X->s & 2 ) >> 1;
+ Y_is_negative = ( Y->s & 2 ) >> 1;
+
+ /*
+ * If the signs are different, then the positive operand is the bigger.
+ * That is if X is negative (X_is_negative == 1), then X < Y is true and it
+ * is false if X is positive (X_is_negative == 0).
+ */
+ cond = ( X_is_negative ^ Y_is_negative );
+ *ret = cond & X_is_negative;
+
+ /*
+ * This is a constant-time function. We might have the result, but we still
+ * need to go through the loop. Record if we have the result already.
+ */
+ done = cond;
+
+ for( i = X->n; i > 0; i-- )
+ {
+ /*
+ * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
+ * X and Y are negative.
+ *
+ * Again even if we can make a decision, we just mark the result and
+ * the fact that we are done and continue looping.
+ */
+ cond = mbedtls_ct_mpi_uint_lt( Y->p[i - 1], X->p[i - 1] );
+ *ret |= cond & ( 1 - done ) & X_is_negative;
+ done |= cond;
+
+ /*
+ * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
+ * X and Y are positive.
+ *
+ * Again even if we can make a decision, we just mark the result and
+ * the fact that we are done and continue looping.
+ */
+ cond = mbedtls_ct_mpi_uint_lt( X->p[i - 1], Y->p[i - 1] );
+ *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
+ done |= cond;
+ }
+
+ return( 0 );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+int mbedtls_ct_rsaes_pkcs1_v15_unpadding( int mode,
+ unsigned char *input,
+ size_t ilen,
+ unsigned char *output,
+ size_t output_max_len,
+ size_t *olen )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t i, plaintext_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;
+
+ plaintext_max_size = ( output_max_len > ilen - 11 ) ? ilen - 11
+ : output_max_len;
+
+ /* Check and get padding length in constant time and constant
+ * memory trace. The first byte must be 0. */
+ bad |= input[0];
+
+ if( mode == MBEDTLS_RSA_PRIVATE )
+ {
+ /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
+ * where PS must be at least 8 nonzero bytes. */
+ bad |= input[1] ^ MBEDTLS_RSA_CRYPT;
+
+ /* 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 |= ((input[i] | (unsigned char)-input[i]) >> 7) ^ 1;
+ pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
+ }
+ }
+ else
+ {
+ /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
+ * where PS must be at least 8 bytes with the value 0xFF. */
+ bad |= input[1] ^ MBEDTLS_RSA_SIGN;
+
+ /* 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 |= mbedtls_ct_uint_if( input[i], 0, 1 );
+ pad_count += mbedtls_ct_uint_if( pad_done, 0, 1 );
+ bad |= mbedtls_ct_uint_if( pad_done, 0, input[i] ^ 0xFF );
+ }
+ }
+
+ /* If pad_done is still zero, there's no data, only unfinished padding. */
+ bad |= mbedtls_ct_uint_if( pad_done, 0, 1 );
+
+ /* There must be at least 8 bytes of padding. */
+ bad |= mbedtls_ct_size_gt( 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 = mbedtls_ct_uint_if(
+ 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 = mbedtls_ct_size_gt( 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) mbedtls_ct_uint_if(
+ bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
+ mbedtls_ct_uint_if( 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 = mbedtls_ct_uint_mask( bad | output_too_large );
+ for( i = 11; i < ilen; i++ )
+ input[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 = mbedtls_ct_uint_if( 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. */
+ mbedtls_ct_mem_move_to_left( input + ilen - plaintext_max_size,
+ plaintext_max_size,
+ plaintext_max_size - plaintext_size );
+
+ /* Finally copy the decrypted plaintext plus trailing zeros into the output
+ * buffer. If output_max_len is 0, then output may be an invalid pointer
+ * and the result of memcpy() would be undefined; prevent undefined
+ * behavior making sure to depend only on output_max_len (the size of the
+ * user-provided output buffer), which is independent from plaintext
+ * length, validity of padding, success of the decryption, and other
+ * secrets. */
+ if( output_max_len != 0 )
+ memcpy( output, input + 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;
+
+ return( ret );
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
diff --git a/thirdparty/mbedtls/library/constant_time_internal.h b/thirdparty/mbedtls/library/constant_time_internal.h
new file mode 100644
index 0000000000..bbb3a90670
--- /dev/null
+++ b/thirdparty/mbedtls/library/constant_time_internal.h
@@ -0,0 +1,329 @@
+/**
+ * Constant-time functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
+#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "mbedtls/ssl_internal.h"
+#endif
+
+#include <stddef.h>
+
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (unsigned) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value The value to analyze.
+ *
+ * \return Zero if \p value is zero, otherwise all-bits-one.
+ */
+unsigned mbedtls_ct_uint_mask( unsigned value );
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (size_t) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value The value to analyze.
+ *
+ * \return Zero if \p value is zero, otherwise all-bits-one.
+ */
+size_t mbedtls_ct_size_mask( size_t value );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (mbedtls_mpi_uint) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value The value to analyze.
+ *
+ * \return Zero if \p value is zero, otherwise all-bits-one.
+ */
+mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask( mbedtls_mpi_uint value );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Constant-flow mask generation for "greater or equal" comparison:
+ * - if \p x >= \p y, return all-bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return All-bits-one if \p x is greater or equal than \p y,
+ * otherwise zero.
+ */
+size_t mbedtls_ct_size_mask_ge( size_t x,
+ size_t y );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+/** Constant-flow boolean "equal" comparison:
+ * return x == y
+ *
+ * This is equivalent to \p x == \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return 1 if \p x equals to \p y, otherwise 0.
+ */
+unsigned mbedtls_ct_size_bool_eq( size_t x,
+ size_t y );
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Decide if an integer is less than the other, without branches.
+ *
+ * This is equivalent to \p x < \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return 1 if \p x is less than \p y, otherwise 0.
+ */
+unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
+ const mbedtls_mpi_uint y );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+/** Choose between two integer values without branches.
+ *
+ * This is equivalent to `condition ? if1 : if0`, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param condition Condition to test.
+ * \param if1 Value to use if \p condition is nonzero.
+ * \param if0 Value to use if \p condition is zero.
+ *
+ * \return \c if1 if \p condition is nonzero, otherwise \c if0.
+ */
+unsigned mbedtls_ct_uint_if( unsigned condition,
+ unsigned if1,
+ unsigned if0 );
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Conditionally assign a value without branches.
+ *
+ * This is equivalent to `if ( condition ) dest = src`, but is likely
+ * to be compiled to code using bitwise operation rather than a branch.
+ *
+ * \param n \p dest and \p src must be arrays of limbs of size n.
+ * \param dest The MPI to conditionally assign to. This must point
+ * to an initialized MPI.
+ * \param src The MPI to be assigned from. This must point to an
+ * initialized MPI.
+ * \param condition Condition to test, must be 0 or 1.
+ */
+void mbedtls_ct_mpi_uint_cond_assign( size_t n,
+ mbedtls_mpi_uint *dest,
+ const mbedtls_mpi_uint *src,
+ unsigned char condition );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_BASE64_C)
+
+/** Given a value in the range 0..63, return the corresponding Base64 digit.
+ *
+ * The implementation assumes that letters are consecutive (e.g. ASCII
+ * but not EBCDIC).
+ *
+ * \param value A value in the range 0..63.
+ *
+ * \return A base64 digit converted from \p value.
+ */
+unsigned char mbedtls_ct_base64_enc_char( unsigned char value );
+
+/** Given a Base64 digit, return its value.
+ *
+ * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
+ * return -1.
+ *
+ * The implementation assumes that letters are consecutive (e.g. ASCII
+ * but not EBCDIC).
+ *
+ * \param c A base64 digit.
+ *
+ * \return The value of the base64 digit \p c.
+ */
+signed char mbedtls_ct_base64_dec_value( unsigned char c );
+
+#endif /* MBEDTLS_BASE64_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Conditional memcpy without branches.
+ *
+ * This is equivalent to `if ( c1 == c2 ) memcpy(dest, src, len)`, but is likely
+ * to be compiled to code using bitwise operation rather than a branch.
+ *
+ * \param dest The pointer to conditionally copy to.
+ * \param src The pointer to copy from. Shouldn't overlap with \p dest.
+ * \param len The number of bytes to copy.
+ * \param c1 The first value to analyze in the condition.
+ * \param c2 The second value to analyze in the condition.
+ */
+void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
+ const unsigned char *src,
+ size_t len,
+ size_t c1, size_t c2 );
+
+/** Copy data from a secret position with constant flow.
+ *
+ * This function copies \p len bytes from \p src_base + \p offset_secret to \p
+ * dst, with a code flow and memory access pattern that does not depend on \p
+ * offset_secret, but only on \p offset_min, \p offset_max and \p len.
+ * Functionally equivalent to `memcpy(dst, src + offset_secret, len)`.
+ *
+ * \param dest The destination buffer. This must point to a writable
+ * buffer of at least \p len bytes.
+ * \param src The base of the source buffer. This must point to a
+ * readable buffer of at least \p offset_max + \p len
+ * bytes. Shouldn't overlap with \p dest.
+ * \param offset The offset in the source buffer from which to copy.
+ * This must be no less than \p offset_min and no greater
+ * than \p offset_max.
+ * \param offset_min The minimal value of \p offset.
+ * \param offset_max The maximal value of \p offset.
+ * \param len The number of bytes to copy.
+ */
+void mbedtls_ct_memcpy_offset( unsigned char *dest,
+ const unsigned char *src,
+ size_t offset,
+ size_t offset_min,
+ size_t offset_max,
+ size_t len );
+
+/** Compute the HMAC of variable-length data with constant flow.
+ *
+ * This function computes the HMAC of the concatenation of \p add_data and \p
+ * data, and does with a code flow and memory access pattern that does not
+ * depend on \p data_len_secret, but only on \p min_data_len and \p
+ * max_data_len. In particular, this function always reads exactly \p
+ * max_data_len bytes from \p data.
+ *
+ * \param ctx The HMAC context. It must have keys configured
+ * with mbedtls_md_hmac_starts() and use one of the
+ * following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
+ * It is reset using mbedtls_md_hmac_reset() after
+ * the computation is complete to prepare for the
+ * next computation.
+ * \param add_data The first part of the message whose HMAC is being
+ * calculated. This must point to a readable buffer
+ * of \p add_data_len bytes.
+ * \param add_data_len The length of \p add_data in bytes.
+ * \param data The buffer containing the second part of the
+ * message. This must point to a readable buffer
+ * of \p max_data_len bytes.
+ * \param data_len_secret The length of the data to process in \p data.
+ * This must be no less than \p min_data_len and no
+ * greater than \p max_data_len.
+ * \param min_data_len The minimal length of the second part of the
+ * message, read from \p data.
+ * \param max_data_len The maximal length of the second part of the
+ * message, read from \p data.
+ * \param output The HMAC will be written here. This must point to
+ * a writable buffer of sufficient size to hold the
+ * HMAC value.
+ *
+ * \retval 0 on success.
+ * \retval #MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
+ * The hardware accelerator failed.
+ */
+int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
+ const unsigned char *add_data,
+ size_t add_data_len,
+ const unsigned char *data,
+ size_t data_len_secret,
+ size_t min_data_len,
+ size_t max_data_len,
+ unsigned char *output );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** This function performs the unpadding part of a PKCS#1 v1.5 decryption
+ * operation (EME-PKCS1-v1_5 decoding).
+ *
+ * \note The return value from this function is a sensitive value
+ * (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
+ * in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
+ * is often a situation that an attacker can provoke and leaking which
+ * one is the result is precisely the information the attacker wants.
+ *
+ * \param mode The mode of operation. This must be either
+ * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param input The input buffer which is the payload inside PKCS#1v1.5
+ * encryption padding, called the "encoded message EM"
+ * by the terminology.
+ * \param ilen The length of the payload in the \p input buffer.
+ * \param output The buffer for the payload, called "message M" by the
+ * PKCS#1 terminology. This must be a writable buffer of
+ * length \p output_max_len bytes.
+ * \param olen The address at which to store the length of
+ * the payload. This must not be \c NULL.
+ * \param output_max_len The length in bytes of the output buffer \p output.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
+ * The output buffer is too small for the unpadded payload.
+ * \return #MBEDTLS_ERR_RSA_INVALID_PADDING
+ * The input doesn't contain properly formatted padding.
+ */
+int mbedtls_ct_rsaes_pkcs1_v15_unpadding( int mode,
+ unsigned char *input,
+ size_t ilen,
+ unsigned char *output,
+ size_t output_max_len,
+ size_t *olen );
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */
diff --git a/thirdparty/mbedtls/library/constant_time_invasive.h b/thirdparty/mbedtls/library/constant_time_invasive.h
new file mode 100644
index 0000000000..4620ca1379
--- /dev/null
+++ b/thirdparty/mbedtls/library/constant_time_invasive.h
@@ -0,0 +1,51 @@
+/**
+ * \file constant_time_invasive.h
+ *
+ * \brief Constant-time module: interfaces for invasive testing only.
+ *
+ * The interfaces in this file are intended for testing purposes only.
+ * They SHOULD NOT be made available in library integrations except when
+ * building the library for testing.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_INVASIVE_H
+#define MBEDTLS_CONSTANT_TIME_INVASIVE_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_TEST_HOOKS)
+
+/** Turn a value into a mask:
+ * - if \p low <= \p c <= \p high,
+ * return the all-bits 1 mask, aka (unsigned) -1
+ * - otherwise, return the all-bits 0 mask, aka 0
+ *
+ * \param low The value to analyze.
+ * \param high The value to analyze.
+ * \param c The value to analyze.
+ *
+ * \return All-bits-one if \p low <= \p c <= \p high, otherwise zero.
+ */
+unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low,
+ unsigned char high,
+ unsigned char c );
+
+#endif /* MBEDTLS_TEST_HOOKS */
+
+#endif /* MBEDTLS_CONSTANT_TIME_INVASIVE_H */
diff --git a/thirdparty/mbedtls/library/ctr_drbg.c b/thirdparty/mbedtls/library/ctr_drbg.c
index 90264e844a..a604ec0761 100644
--- a/thirdparty/mbedtls/library/ctr_drbg.c
+++ b/thirdparty/mbedtls/library/ctr_drbg.c
@@ -2,13 +2,7 @@
* CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The NIST SP 800-90 DRBGs are described in the following publication.
@@ -49,16 +22,13 @@
* http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -81,6 +51,9 @@
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
+ /* Indicate that the entropy nonce length is not set explicitly.
+ * See mbedtls_ctr_drbg_set_nonce_len(). */
+ ctx->reseed_counter = -1;
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
}
@@ -102,19 +75,49 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
mbedtls_aes_free( &ctx->aes_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
+ ctx->reseed_counter = -1;
}
-void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
+void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
+ int resistance )
{
ctx->prediction_resistance = resistance;
}
-void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
+void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
+ size_t len )
{
ctx->entropy_len = len;
}
-void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
+int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
+ size_t len )
+{
+ /* If mbedtls_ctr_drbg_seed() has already been called, it's
+ * too late. Return the error code that's closest to making sense. */
+ if( ctx->f_entropy != NULL )
+ return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
+
+ if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
+ return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+#if SIZE_MAX > INT_MAX
+ /* This shouldn't be an issue because
+ * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
+ * configuration, but make sure anyway. */
+ if( len > INT_MAX )
+ return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+#endif
+
+ /* For backward compatibility with Mbed TLS <= 2.19, store the
+ * entropy nonce length in a field that already exists, but isn't
+ * used until after the initial seeding. */
+ /* Due to the capping of len above, the value fits in an int. */
+ ctx->reseed_counter = (int) len;
+ return( 0 );
+}
+
+void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
+ int interval )
{
ctx->reseed_interval = interval;
}
@@ -122,7 +125,8 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int in
static int block_cipher_df( unsigned char *output,
const unsigned char *data, size_t data_len )
{
- unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
+ unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
+ MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
@@ -136,7 +140,8 @@ static int block_cipher_df( unsigned char *output,
if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
- memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
+ memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
+ MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
mbedtls_aes_init( &aes_ctx );
/*
@@ -147,11 +152,8 @@ static int block_cipher_df( unsigned char *output,
* (Total is padded to a multiple of 16-bytes with zeroes)
*/
p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
- *p++ = ( data_len >> 24 ) & 0xff;
- *p++ = ( data_len >> 16 ) & 0xff;
- *p++ = ( data_len >> 8 ) & 0xff;
- *p++ = ( data_len ) & 0xff;
- p += 3;
+ MBEDTLS_PUT_UINT32_BE( data_len, p, 0);
+ p += 4 + 3;
*p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
memcpy( p, data, data_len );
p[data_len] = 0x80;
@@ -161,7 +163,8 @@ static int block_cipher_df( unsigned char *output,
for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
key[i] = i;
- if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
@@ -183,7 +186,8 @@ static int block_cipher_df( unsigned char *output,
use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
- if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
+ chain, chain ) ) != 0 )
{
goto exit;
}
@@ -200,7 +204,8 @@ static int block_cipher_df( unsigned char *output,
/*
* Do final encryption with reduced data
*/
- if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
@@ -209,7 +214,8 @@ static int block_cipher_df( unsigned char *output,
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
{
- if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
+ iv, iv ) ) != 0 )
{
goto exit;
}
@@ -245,7 +251,7 @@ exit:
* ctx->counter = V
*/
static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
- const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
+ const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
{
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = tmp;
@@ -266,8 +272,11 @@ 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 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
+ ctx->counter, p ) ) != 0 )
+ {
goto exit;
+ }
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
}
@@ -278,9 +287,13 @@ 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 )
+ if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ {
goto exit;
- memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
+ }
+ memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
+ MBEDTLS_CTR_DRBG_BLOCKSIZE );
exit:
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
@@ -304,7 +317,7 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
size_t add_len )
{
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( add_len == 0 )
return( 0 );
@@ -333,7 +346,7 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
- * mbedtls_ctr_drbg_reseed(ctx, additional, len)
+ * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
* implements
* CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
* -> new_working_state
@@ -341,51 +354,57 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
* ctx contains working_state
* additional[:len] = additional_input
* and entropy_input comes from calling ctx->f_entropy
+ * for (ctx->entropy_len + nonce_len) bytes
* and with output
* ctx contains new_working_state
*/
-int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
- const unsigned char *additional, size_t len )
+static int mbedtls_ctr_drbg_reseed_internal( mbedtls_ctr_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t len,
+ size_t nonce_len )
{
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
- len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
+ if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
+ return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+ if( nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
+ return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+ if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
- /*
- * Gather entropy_len bytes of entropy to seed state
- */
- if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
- ctx->entropy_len ) )
+ /* Gather entropy_len bytes of entropy to seed state. */
+ if( 0 != ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) )
{
return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
}
-
seedlen += ctx->entropy_len;
- /*
- * Add additional data
- */
- if( additional && len )
+ /* Gather entropy for a nonce if requested. */
+ if( nonce_len != 0 )
+ {
+ if( 0 != ctx->f_entropy( ctx->p_entropy, seed + seedlen, nonce_len ) )
+ {
+ return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
+ }
+ seedlen += nonce_len;
+ }
+
+ /* Add additional data if provided. */
+ if( additional != NULL && len != 0 )
{
memcpy( seed + seedlen, additional, len );
seedlen += len;
}
- /*
- * Reduce to 384 bits
- */
+ /* Reduce to 384 bits. */
if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
goto exit;
- /*
- * Update state
- */
+ /* Update state. */
if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
goto exit;
ctx->reseed_counter = 1;
@@ -395,6 +414,25 @@ exit:
return( ret );
}
+int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
+ const unsigned char *additional, size_t len )
+{
+ return( mbedtls_ctr_drbg_reseed_internal( ctx, additional, len, 0 ) );
+}
+
+/* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
+ * is sufficient to achieve the maximum security strength given the key
+ * size and entropy length. If there is enough entropy in the initial
+ * call to the entropy function to serve as both the entropy input and
+ * the nonce, don't make a second call to get a nonce. */
+static size_t good_nonce_len( size_t entropy_len )
+{
+ if( entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 )
+ return( 0 );
+ else
+ return( ( entropy_len + 1 ) / 2 );
+}
+
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
* implements
@@ -412,8 +450,9 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *custom,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
+ size_t nonce_len;
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
@@ -429,33 +468,30 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
if( ctx->entropy_len == 0 )
ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
-
- /*
- * Initialize with an empty key
- */
- if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ /* ctx->reseed_counter contains the desired amount of entropy to
+ * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
+ * If it's -1, indicating that the entropy nonce length was not set
+ * explicitly, use a sufficiently large nonce for security. */
+ nonce_len = ( ctx->reseed_counter >= 0 ?
+ (size_t) ctx->reseed_counter :
+ good_nonce_len( ctx->entropy_len ) );
+
+ /* Initialize with an empty key. */
+ if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
- if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
+ /* Do the initial seeding. */
+ if( ( ret = mbedtls_ctr_drbg_reseed_internal( ctx, custom, len,
+ nonce_len ) ) != 0 )
{
return( ret );
}
return( 0 );
}
-/* Backward compatibility wrapper */
-int mbedtls_ctr_drbg_seed_entropy_len(
- mbedtls_ctr_drbg_context *ctx,
- int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
- const unsigned char *custom, size_t len,
- size_t entropy_len )
-{
- mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len );
- return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
-}
-
/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
* mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
* implements
@@ -525,11 +561,14 @@ 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 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
+ ctx->counter, tmp ) ) != 0 )
+ {
goto exit;
+ }
- use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
- output_len;
+ use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE )
+ ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
/*
* Copy random block to destination
*/
@@ -549,9 +588,10 @@ exit:
return( ret );
}
-int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
+int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
+ size_t output_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
#if defined(MBEDTLS_THREADING_C)
@@ -570,7 +610,8 @@ int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_l
}
#if defined(MBEDTLS_FS_IO)
-int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
+int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx,
+ const char *path )
{
int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
FILE *f;
@@ -579,13 +620,19 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
if( ( f = fopen( path, "wb" ) ) == NULL )
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
- if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
+ if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
+ MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
goto exit;
- if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
+ if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) !=
+ MBEDTLS_CTR_DRBG_MAX_INPUT )
+ {
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
+ }
else
+ {
ret = 0;
+ }
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -594,7 +641,8 @@ exit:
return( ret );
}
-int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
+int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
+ const char *path )
{
int ret = 0;
FILE *f = NULL;
@@ -633,45 +681,135 @@ exit:
#if defined(MBEDTLS_SELF_TEST)
-static const unsigned char entropy_source_pr[96] =
- { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
- 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
- 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
- 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
- 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
- 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
- 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
- 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
- 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
- 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
- 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
- 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
-
-static const unsigned char entropy_source_nopr[64] =
- { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
- 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
- 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
- 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
- 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
- 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
- 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
- 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
-
-static const unsigned char nonce_pers_pr[16] =
- { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
- 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
-
-static const unsigned char nonce_pers_nopr[16] =
- { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
- 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
-
-static const unsigned char result_pr[16] =
- { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
- 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
-
-static const unsigned char result_nopr[16] =
- { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
- 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
+/* The CTR_DRBG NIST test vectors used here are available at
+ * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip
+ *
+ * The parameters used to derive the test data are:
+ *
+ * [AES-128 use df]
+ * [PredictionResistance = True/False]
+ * [EntropyInputLen = 128]
+ * [NonceLen = 64]
+ * [PersonalizationStringLen = 128]
+ * [AdditionalInputLen = 0]
+ * [ReturnedBitsLen = 512]
+ *
+ * [AES-256 use df]
+ * [PredictionResistance = True/False]
+ * [EntropyInputLen = 256]
+ * [NonceLen = 128]
+ * [PersonalizationStringLen = 256]
+ * [AdditionalInputLen = 0]
+ * [ReturnedBitsLen = 512]
+ *
+ */
+
+#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
+static const unsigned char entropy_source_pr[] =
+ { 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb,
+ 0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92,
+ 0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8,
+ 0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20,
+ 0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0,
+ 0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad,
+ 0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 };
+
+static const unsigned char entropy_source_nopr[] =
+ { 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45,
+ 0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9,
+ 0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20,
+ 0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f,
+ 0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c };
+
+static const unsigned char pers_pr[] =
+ { 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
+ 0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };
+
+static const unsigned char pers_nopr[] =
+ { 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
+ 0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };
+
+static const unsigned char result_pr[] =
+ { 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66,
+ 0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff,
+ 0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10,
+ 0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30,
+ 0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4,
+ 0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc,
+ 0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06,
+ 0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf };
+
+static const unsigned char result_nopr[] =
+ { 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13,
+ 0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0,
+ 0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf,
+ 0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2,
+ 0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7,
+ 0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2,
+ 0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02,
+ 0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 };
+#else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
+
+static const unsigned char entropy_source_pr[] =
+ { 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49,
+ 0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a,
+ 0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85,
+ 0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e,
+ 0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15,
+ 0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45,
+ 0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8,
+ 0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c,
+ 0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3,
+ 0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce,
+ 0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e,
+ 0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76,
+ 0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77,
+ 0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe };
+
+static const unsigned char entropy_source_nopr[] =
+ { 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d,
+ 0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0,
+ 0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73,
+ 0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c,
+ 0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2,
+ 0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1,
+ 0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a,
+ 0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb,
+ 0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a,
+ 0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 };
+
+static const unsigned char pers_pr[] =
+ { 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33,
+ 0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e,
+ 0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0,
+ 0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 };
+
+static const unsigned char pers_nopr[] =
+ { 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29,
+ 0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf,
+ 0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb,
+ 0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b };
+
+static const unsigned char result_pr[] =
+ { 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85,
+ 0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d,
+ 0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62,
+ 0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d,
+ 0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb,
+ 0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39,
+ 0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40,
+ 0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 };
+
+static const unsigned char result_nopr[] =
+ { 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad,
+ 0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3,
+ 0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b,
+ 0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14,
+ 0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54,
+ 0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30,
+ 0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a,
+ 0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 };
+#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
static size_t test_offset;
static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
@@ -690,13 +828,15 @@ static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
return( 1 ); \
}
+#define SELF_TEST_OUPUT_DISCARD_LENGTH 64
+
/*
* Checkup routine
*/
int mbedtls_ctr_drbg_self_test( int verbose )
{
mbedtls_ctr_drbg_context ctx;
- unsigned char buf[16];
+ unsigned char buf[ sizeof( result_pr ) ];
mbedtls_ctr_drbg_init( &ctx );
@@ -707,15 +847,16 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
test_offset = 0;
- mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE );
+ mbedtls_ctr_drbg_set_nonce_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2 );
CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_pr,
- nonce_pers_pr, 16 ) );
+ pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) );
+ CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) );
mbedtls_ctr_drbg_free( &ctx );
@@ -731,15 +872,16 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_ctr_drbg_init( &ctx );
test_offset = 0;
- mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
+ mbedtls_ctr_drbg_set_nonce_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2 );
CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_nopr,
- nonce_pers_nopr, 16 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
+ pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
- CHK( memcmp( buf, result_nopr, 16 ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) );
+ CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) );
mbedtls_ctr_drbg_free( &ctx );
diff --git a/thirdparty/mbedtls/library/debug.c b/thirdparty/mbedtls/library/debug.c
index 9caa361d44..e1086008af 100644
--- a/thirdparty/mbedtls/library/debug.c
+++ b/thirdparty/mbedtls/library/debug.c
@@ -2,13 +2,7 @@
* Debugging routines
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_DEBUG_C)
@@ -60,9 +29,11 @@
#define mbedtls_free free
#define mbedtls_time_t time_t
#define mbedtls_snprintf snprintf
+#define mbedtls_vsnprintf vsnprintf
#endif
#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
#include <stdarg.h>
#include <stdio.h>
@@ -103,13 +74,14 @@ static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level,
#endif
}
+MBEDTLS_PRINTF_ATTRIBUTE(5, 6)
void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *format, ... )
{
va_list argp;
char str[DEBUG_BUF_SIZE];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( NULL == ssl ||
NULL == ssl->conf ||
@@ -120,20 +92,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
}
va_start( argp, format );
-#if defined(_WIN32)
-#if defined(_TRUNCATE) && !defined(__MINGW32__)
- ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
-#else
- ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
- if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE )
- {
- str[DEBUG_BUF_SIZE-1] = '\0';
- ret = -1;
- }
-#endif
-#else
- ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
-#endif
+ ret = mbedtls_vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
va_end( argp );
if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 )
@@ -168,7 +127,7 @@ void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
return;
mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n",
- text, ret, -ret );
+ text, ret, (unsigned int) -ret );
debug_send_line( ssl, level, file, line, str );
}
diff --git a/thirdparty/mbedtls/library/des.c b/thirdparty/mbedtls/library/des.c
index 0867064403..91d22b5d90 100644
--- a/thirdparty/mbedtls/library/des.c
+++ b/thirdparty/mbedtls/library/des.c
@@ -2,13 +2,7 @@
* FIPS-46-3 compliant Triple-DES implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* DES, on which TDES is based, was originally designed by Horst Feistel
@@ -50,11 +23,7 @@
* http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_DES_C)
@@ -76,29 +45,6 @@
#if !defined(MBEDTLS_DES_ALT)
/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
-/*
* Expanded DES S-boxes
*/
static const uint32_t SB1[64] =
@@ -455,8 +401,8 @@ void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KE
int i;
uint32_t X, Y, T;
- GET_UINT32_BE( X, key, 0 );
- GET_UINT32_BE( Y, key, 4 );
+ X = MBEDTLS_GET_UINT32_BE( key, 0 );
+ Y = MBEDTLS_GET_UINT32_BE( key, 4 );
/*
* Permuted Choice 1
@@ -665,8 +611,8 @@ int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
SK = ctx->sk;
- GET_UINT32_BE( X, input, 0 );
- GET_UINT32_BE( Y, input, 4 );
+ X = MBEDTLS_GET_UINT32_BE( input, 0 );
+ Y = MBEDTLS_GET_UINT32_BE( input, 4 );
DES_IP( X, Y );
@@ -678,8 +624,8 @@ int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
DES_FP( Y, X );
- PUT_UINT32_BE( Y, output, 0 );
- PUT_UINT32_BE( X, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( X, output, 4 );
return( 0 );
}
@@ -697,7 +643,7 @@ int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
unsigned char *output )
{
int i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char temp[8];
if( length % 8 )
@@ -759,8 +705,8 @@ int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
SK = ctx->sk;
- GET_UINT32_BE( X, input, 0 );
- GET_UINT32_BE( Y, input, 4 );
+ X = MBEDTLS_GET_UINT32_BE( input, 0 );
+ Y = MBEDTLS_GET_UINT32_BE( input, 4 );
DES_IP( X, Y );
@@ -784,8 +730,8 @@ int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
DES_FP( Y, X );
- PUT_UINT32_BE( Y, output, 0 );
- PUT_UINT32_BE( X, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( X, output, 4 );
return( 0 );
}
@@ -803,7 +749,7 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
unsigned char *output )
{
int i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char temp[8];
if( length % 8 )
@@ -874,16 +820,16 @@ static const unsigned char des3_test_buf[8] =
static const unsigned char des3_test_ecb_dec[3][8] =
{
- { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
- { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
- { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
+ { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
+ { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
+ { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
};
static const unsigned char des3_test_ecb_enc[3][8] =
{
- { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
- { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
- { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
+ { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
+ { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
+ { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
};
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -894,16 +840,16 @@ static const unsigned char des3_test_iv[8] =
static const unsigned char des3_test_cbc_dec[3][8] =
{
- { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
- { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
- { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
+ { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
+ { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
+ { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
};
static const unsigned char des3_test_cbc_enc[3][8] =
{
- { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
- { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
- { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
+ { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
+ { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
+ { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
};
#endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -970,7 +916,7 @@ int mbedtls_des_self_test( int verbose )
if( ret != 0 )
goto exit;
- for( j = 0; j < 10000; j++ )
+ for( j = 0; j < 100; j++ )
{
if( u == 0 )
ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
@@ -1051,7 +997,7 @@ int mbedtls_des_self_test( int verbose )
if( v == MBEDTLS_DES_DECRYPT )
{
- for( j = 0; j < 10000; j++ )
+ for( j = 0; j < 100; j++ )
{
if( u == 0 )
ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
@@ -1063,7 +1009,7 @@ int mbedtls_des_self_test( int verbose )
}
else
{
- for( j = 0; j < 10000; j++ )
+ for( j = 0; j < 100; j++ )
{
unsigned char tmp[8];
diff --git a/thirdparty/mbedtls/library/dhm.c b/thirdparty/mbedtls/library/dhm.c
index 535b698ce6..88e148bb80 100644
--- a/thirdparty/mbedtls/library/dhm.c
+++ b/thirdparty/mbedtls/library/dhm.c
@@ -2,13 +2,7 @@
* Diffie-Hellman-Merkle key exchange
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The following sources were referenced in the design of this implementation
@@ -52,16 +25,13 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_DHM_C)
#include "mbedtls/dhm.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -109,7 +79,7 @@ static int dhm_read_bignum( mbedtls_mpi *X,
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
- return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret ) );
(*p) += n;
@@ -161,7 +131,7 @@ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
unsigned char **p,
const unsigned char *end )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( p != NULL && *p != NULL );
DHM_VALIDATE_RET( end != NULL );
@@ -185,20 +155,10 @@ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret, count;
- size_t m_size = mbedtls_mpi_size( M );
- size_t m_bitlen = mbedtls_mpi_bitlen( M );
-
- count = 0;
- do
- {
- if( count++ > 30 )
- return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+ int ret;
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, m_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, ( m_size * 8 ) - m_bitlen ) );
- }
- while( dhm_check_range( R, M ) != 0 );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_random( R, 3, M, f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( R, R, 1 ) );
cleanup:
return( ret );
@@ -271,8 +231,8 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
p + 2, \
( n ) ) ); \
- *p++ = (unsigned char)( ( n ) >> 8 ); \
- *p++ = (unsigned char)( ( n ) ); \
+ *p++ = MBEDTLS_BYTE_1( n ); \
+ *p++ = MBEDTLS_BYTE_0( n ); \
p += ( n ); \
} while( 0 )
@@ -291,7 +251,7 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
cleanup:
if( ret != 0 && ret > -128 )
- return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
return( ret );
}
@@ -302,7 +262,7 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
const mbedtls_mpi *P,
const mbedtls_mpi *G )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( P != NULL );
DHM_VALIDATE_RET( G != NULL );
@@ -310,7 +270,7 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
{
- return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
}
ctx->len = mbedtls_mpi_size( &ctx->P );
@@ -323,7 +283,7 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
const unsigned char *input, size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( input != NULL );
@@ -331,7 +291,7 @@ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
- return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret ) );
return( 0 );
}
@@ -362,8 +322,7 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
cleanup:
if( ret != 0 && ret > -128 )
- return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
-
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
return( ret );
}
@@ -443,7 +402,7 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi GYb;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( output != NULL );
@@ -487,7 +446,7 @@ cleanup:
mbedtls_mpi_free( &GYb );
if( ret != 0 )
- return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret ) );
return( 0 );
}
@@ -521,7 +480,7 @@ void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
size_t dhminlen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
unsigned char *p, *end;
#if defined(MBEDTLS_PEM_PARSE_C)
@@ -569,7 +528,7 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
goto exit;
}
@@ -578,7 +537,7 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
{
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
goto exit;
}
@@ -592,13 +551,13 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
mbedtls_mpi_free( &rec );
if ( ret != 0 )
{
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
goto exit;
}
if ( p != end )
{
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
goto exit;
}
}
@@ -675,7 +634,7 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
*/
int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
DHM_VALIDATE_RET( dhm != NULL );
@@ -727,7 +686,7 @@ static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_param
*/
int mbedtls_dhm_self_test( int verbose )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_dhm_context dhm;
mbedtls_dhm_init( &dhm );
diff --git a/thirdparty/mbedtls/library/ecdh.c b/thirdparty/mbedtls/library/ecdh.c
index 8c27e4e196..9dfa868063 100644
--- a/thirdparty/mbedtls/library/ecdh.c
+++ b/thirdparty/mbedtls/library/ecdh.c
@@ -2,13 +2,7 @@
* Elliptic curve Diffie-Hellman
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -51,16 +24,13 @@
* RFC 4492
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ECDH_C)
#include "mbedtls/ecdh.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -84,6 +54,13 @@ static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
#endif
}
+int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid )
+{
+ /* At this time, all groups support ECDH. */
+ (void) gid;
+ return( 1 );
+}
+
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
/*
* Generate public key (restartable version)
@@ -98,7 +75,7 @@ static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp,
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* If multiplication is in progress, we already generated a privkey */
#if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -139,7 +116,7 @@ static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp,
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point P;
mbedtls_ecp_point_init( &P );
@@ -217,7 +194,7 @@ void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx,
mbedtls_ecp_group_id grp_id )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_ecp_group_load( &ctx->grp, grp_id );
if( ret != 0 )
@@ -240,6 +217,13 @@ int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
#else
switch( grp_id )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECP_DP_CURVE25519:
+ ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED;
+ ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST;
+ ctx->grp_id = grp_id;
+ return( mbedtls_everest_setup( &ctx->ctx.everest_ecdh, grp_id ) );
+#endif
default:
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
@@ -291,6 +275,11 @@ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ mbedtls_everest_free( &ctx->ctx.everest_ecdh );
+ break;
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
ecdh_free_internal( &ctx->ctx.mbed_ecdh );
break;
@@ -313,7 +302,7 @@ static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
void *p_rng,
int restart_enabled )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t grp_len, pt_len;
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
@@ -356,7 +345,7 @@ static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
}
/*
- * Setup and write the ServerKeyExhange parameters (RFC 4492)
+ * Setup and write the ServerKeyExchange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
@@ -385,6 +374,11 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_make_params( &ctx->ctx.everest_ecdh, olen,
+ buf, blen, f_rng, p_rng ) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
ctx->point_format, buf, blen,
@@ -415,7 +409,7 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf,
const unsigned char *end )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group_id grp_id;
ECDH_VALIDATE_RET( ctx != NULL );
ECDH_VALIDATE_RET( buf != NULL );
@@ -434,6 +428,11 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_read_params( &ctx->ctx.everest_ecdh,
+ buf, end) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh,
buf, end ) );
@@ -447,7 +446,7 @@ static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx,
const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* If it's not our key, just import the public part as Qp */
if( side == MBEDTLS_ECDH_THEIRS )
@@ -471,7 +470,7 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECDH_VALIDATE_RET( ctx != NULL );
ECDH_VALIDATE_RET( key != NULL );
ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
@@ -498,6 +497,16 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ {
+ mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ?
+ MBEDTLS_EVEREST_ECDH_OURS :
+ MBEDTLS_EVEREST_ECDH_THEIRS;
+ return( mbedtls_everest_get_params( &ctx->ctx.everest_ecdh,
+ key, s) );
+ }
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh,
key, side ) );
@@ -516,7 +525,7 @@ static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx,
void *p_rng,
int restart_enabled )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
#endif
@@ -569,6 +578,11 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_make_public( &ctx->ctx.everest_ecdh, olen,
+ buf, blen, f_rng, p_rng ) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen,
ctx->point_format, buf, blen,
@@ -583,7 +597,7 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx,
const unsigned char *buf, size_t blen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *p = buf;
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p,
@@ -610,6 +624,11 @@ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_read_public( &ctx->ctx.everest_ecdh,
+ buf, blen ) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh,
buf, blen ) );
@@ -628,7 +647,7 @@ static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
void *p_rng,
int restart_enabled )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
#endif
@@ -662,6 +681,10 @@ static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
+
+ if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen );
+
return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
}
@@ -688,6 +711,11 @@ int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_calc_secret( &ctx->ctx.everest_ecdh, olen,
+ buf, blen, f_rng, p_rng ) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf,
blen, f_rng, p_rng,
diff --git a/thirdparty/mbedtls/library/ecdsa.c b/thirdparty/mbedtls/library/ecdsa.c
index 2456238b17..640eb24a26 100644
--- a/thirdparty/mbedtls/library/ecdsa.c
+++ b/thirdparty/mbedtls/library/ecdsa.c
@@ -2,13 +2,7 @@
* Elliptic curve DSA
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -50,11 +23,7 @@
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ECDSA_C)
@@ -76,6 +45,7 @@
#endif
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
/* Parameter validation macros based on platform_util.h */
#define ECDSA_VALIDATE_RET( cond ) \
@@ -257,7 +227,7 @@ static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
const unsigned char *buf, size_t blen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n_size = ( grp->nbits + 7 ) / 8;
size_t use_size = blen > n_size ? n_size : blen;
@@ -294,7 +264,7 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
mbedtls_mpi *pk = &k, *pr = r;
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
- if( grp->N.p == NULL )
+ if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
/* Make sure d is in range 1..n-1 */
@@ -413,6 +383,20 @@ cleanup:
return( ret );
}
+int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid )
+{
+ switch( gid )
+ {
+#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ case MBEDTLS_ECP_DP_CURVE25519: return 0;
+#endif
+#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
+ case MBEDTLS_ECP_DP_CURVE448: return 0;
+#endif
+ default: return 1;
+ }
+}
+
/*
* Compute ECDSA signature of a hashed message
*/
@@ -445,7 +429,7 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_hmac_drbg_context rng_ctx;
mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
@@ -486,6 +470,8 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
sign:
#endif
#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+ (void) f_rng_blind;
+ (void) p_rng_blind;
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, p_rng );
#else
@@ -509,7 +495,6 @@ sign:
mbedtls_hmac_drbg_init( &rng_ctx_blind );
p_rng_blind_det = &rng_ctx_blind;
-
mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info,
data, 2 * grp_len );
ret = mbedtls_hmac_drbg_update_ret( p_rng_blind_det,
@@ -567,6 +552,8 @@ cleanup:
/*
* Deterministic signature wrappers
*/
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
@@ -581,6 +568,7 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
NULL, NULL, NULL ) );
}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
@@ -613,7 +601,7 @@ static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
const mbedtls_mpi *r, const mbedtls_mpi *s,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi e, s_inv, u1, u2;
mbedtls_ecp_point R;
mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
@@ -623,7 +611,7 @@ static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
- if( grp->N.p == NULL )
+ if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
ECDSA_RS_ENTER( ver );
@@ -737,8 +725,8 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
unsigned char *sig, size_t *slen )
{
- int ret;
- unsigned char buf[MBEDTLS_ECDSA_MAX_LEN];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = {0};
unsigned char *p = buf + sizeof( buf );
size_t len = 0;
@@ -766,7 +754,7 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi r, s;
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( hash != NULL );
@@ -861,7 +849,7 @@ int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
const unsigned char *sig, size_t slen,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = (unsigned char *) sig;
const unsigned char *end = sig + slen;
size_t len;
@@ -882,8 +870,8 @@ int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
if( p + len != end )
{
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
goto cleanup;
}
@@ -943,7 +931,7 @@ int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
*/
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( key != NULL );
diff --git a/thirdparty/mbedtls/library/ecjpake.c b/thirdparty/mbedtls/library/ecjpake.c
index 0532a295e6..368b6c7124 100644
--- a/thirdparty/mbedtls/library/ecjpake.c
+++ b/thirdparty/mbedtls/library/ecjpake.c
@@ -2,13 +2,7 @@
* Elliptic curve J-PAKE
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -49,16 +22,13 @@
* available to members of the Thread Group http://threadgroup.org/
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ECJPAKE_C)
#include "mbedtls/ecjpake.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -135,7 +105,7 @@ int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
const unsigned char *secret,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECJPAKE_VALIDATE_RET( ctx != NULL );
ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT ||
@@ -184,7 +154,7 @@ static int ecjpake_write_len_point( unsigned char **p,
const int pf,
const mbedtls_ecp_point *P )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/* Need at least 4 for length plus 1 for point */
@@ -196,10 +166,7 @@ static int ecjpake_write_len_point( unsigned char **p,
if( ret != 0 )
return( ret );
- (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
- (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
- (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
- (*p)[3] = (unsigned char)( ( len ) & 0xFF );
+ MBEDTLS_PUT_UINT32_BE( len, *p, 0 );
*p += 4 + len;
@@ -224,7 +191,7 @@ static int ecjpake_hash( const mbedtls_md_info_t *md_info,
const char *id,
mbedtls_mpi *h )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[ECJPAKE_HASH_BUF_LEN];
unsigned char *p = buf;
const unsigned char *end = buf + sizeof( buf );
@@ -239,10 +206,8 @@ static int ecjpake_hash( const mbedtls_md_info_t *md_info,
if( end - p < 4 )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len ) & 0xFF );
+ MBEDTLS_PUT_UINT32_BE( id_len, p, 0 );
+ p += 4;
if( end < p || (size_t)( end - p ) < id_len )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
@@ -274,7 +239,7 @@ static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
const unsigned char **p,
const unsigned char *end )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point V, VV;
mbedtls_mpi r, h;
size_t r_len;
@@ -303,7 +268,7 @@ static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
r_len = *(*p)++;
- if( end < *p || (size_t)( end - *p ) < r_len )
+ if( end < *p || (size_t)( end - *p ) < r_len || r_len == 0 )
{
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
@@ -349,7 +314,7 @@ static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point V;
mbedtls_mpi v;
mbedtls_mpi h; /* later recycled to hold r */
@@ -382,7 +347,7 @@ static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
goto cleanup;
}
- *(*p)++ = (unsigned char)( len & 0xFF );
+ *(*p)++ = MBEDTLS_BYTE_0( len );
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
*p += len;
@@ -407,7 +372,7 @@ static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
const unsigned char **p,
const unsigned char *end )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( end < *p )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -447,7 +412,7 @@ static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( end < *p )
@@ -482,7 +447,7 @@ static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *p = buf;
const unsigned char *end = buf + len;
@@ -520,7 +485,7 @@ static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = buf;
const unsigned char *end = buf + len;
@@ -578,7 +543,7 @@ static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_ecp_point *B,
const mbedtls_ecp_point *C )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi one;
mbedtls_mpi_init( &one );
@@ -600,7 +565,7 @@ int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *p = buf;
const unsigned char *end = buf + len;
mbedtls_ecp_group grp;
@@ -664,7 +629,7 @@ static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi b; /* Blinding value, then s + N * blinding */
mbedtls_mpi_init( &b );
@@ -693,7 +658,7 @@ int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point G; /* C: GA, S: GB */
mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
mbedtls_mpi xm; /* C: xc, S: xs */
@@ -775,7 +740,7 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point K;
mbedtls_mpi m_xm2_s, one;
unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
@@ -983,7 +948,7 @@ static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
const unsigned char *xm1, size_t len1,
const unsigned char *xm2, size_t len2 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
@@ -1033,7 +998,7 @@ static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
*/
int mbedtls_ecjpake_self_test( int verbose )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecjpake_context cli;
mbedtls_ecjpake_context srv;
unsigned char buf[512], pms[32];
diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c
index a7486c198a..7f9e1045d4 100644
--- a/thirdparty/mbedtls/library/ecp.c
+++ b/thirdparty/mbedtls/library/ecp.c
@@ -2,13 +2,7 @@
* Elliptic curves over GF(p): generic functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -66,11 +39,7 @@
* <http://eprint.iacr.org/2004/342.pdf>
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
/**
* \brief Function level alternative implementation.
@@ -106,8 +75,11 @@
#include "mbedtls/ecp.h"
#include "mbedtls/threading.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include "mbedtls/bn_mul.h"
+#include "ecp_invasive.h"
+
#include <string.h>
#if !defined(MBEDTLS_ECP_ALT)
@@ -135,10 +107,6 @@
#include "mbedtls/hmac_drbg.h"
#elif defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
-#elif defined(MBEDTLS_SHA512_C)
-#include "mbedtls/sha512.h"
-#elif defined(MBEDTLS_SHA256_C)
-#include "mbedtls/sha256.h"
#else
#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
#endif
@@ -210,6 +178,12 @@ static int ecp_drbg_seed( ecp_drbg_context *ctx,
const mbedtls_md_type_t md_type = mbedtls_md_list()[0];
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_type );
+ if( secret_len > MBEDTLS_ECP_MAX_BYTES )
+ {
+ ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
+ goto cleanup;
+ }
+
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
secret_bytes, secret_len ) );
@@ -266,6 +240,12 @@ static int ecp_drbg_seed( ecp_drbg_context *ctx,
int ret;
unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES];
+ if( secret_len > MBEDTLS_ECP_MAX_BYTES )
+ {
+ ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
+ goto cleanup;
+ }
+
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
secret_bytes, secret_len ) );
@@ -278,110 +258,9 @@ cleanup:
return( ret );
}
-#elif defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA256_C)
-
-/* This will be used in the self-test function */
-#define ECP_ONE_STEP_KDF
-
-/*
- * We need to expand secret data (the scalar) into a longer stream of bytes.
- *
- * We'll use the One-Step KDF from NIST SP 800-56C, with option 1 (H is a hash
- * function) and empty FixedInfo. (Though we'll make it fit the DRBG API for
- * convenience, this is not a full-fledged DRBG, but we don't need one here.)
- *
- * We need a basic hash abstraction layer to use whatever SHA-2 is available.
- */
-#if defined(MBEDTLS_SHA512_C)
-
-#define HASH_FUNC( in, ilen, out ) mbedtls_sha512_ret( in, ilen, out, 0 );
-#define HASH_BLOCK_BYTES ( 512 / 8 )
-
-#elif defined(MBEDTLS_SHA256_C)
-
-#define HASH_FUNC( in, ilen, out ) mbedtls_sha256_ret( in, ilen, out, 0 );
-#define HASH_BLOCK_BYTES ( 256 / 8 )
-
-#endif /* SHA512/SHA256 abstraction */
-
-/*
- * State consists of a 32-bit counter plus the secret value.
- *
- * We stored them concatenated in a single buffer as that's what will get
- * passed to the hash function.
- */
-typedef struct {
- size_t total_len;
- uint8_t buf[4 + MBEDTLS_ECP_MAX_BYTES];
-} ecp_drbg_context;
-
-static void ecp_drbg_init( ecp_drbg_context *ctx )
-{
- memset( ctx, 0, sizeof( ecp_drbg_context ) );
-}
-
-static void ecp_drbg_free( ecp_drbg_context *ctx )
-{
- mbedtls_platform_zeroize( ctx, sizeof( ecp_drbg_context ) );
-}
-
-static int ecp_drbg_seed( ecp_drbg_context *ctx,
- const mbedtls_mpi *secret, size_t secret_len )
-{
- ctx->total_len = 4 + secret_len;
- memset( ctx->buf, 0, 4);
- return( mbedtls_mpi_write_binary( secret, ctx->buf + 4, secret_len ) );
-}
-
-static int ecp_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
-{
- ecp_drbg_context *ctx = p_rng;
- int ret;
- size_t len_done = 0;
- uint8_t tmp[HASH_BLOCK_BYTES];
-
- while( len_done < output_len )
- {
- uint8_t use_len;
-
- /* This function is only called for coordinate randomisation, which
- * happens only twice in a scalar multiplication. Each time needs a
- * random value in the range [2, p-1], and gets it by drawing len(p)
- * bytes from this function, and retrying up to 10 times if unlucky.
- *
- * So for the largest curve, each scalar multiplication draws at most
- * 20 * 66 bytes. The minimum block size is 32 (SHA-256), so with
- * rounding that means a most 20 * 3 blocks.
- *
- * Since we don't need to draw more that 255 blocks, don't bother
- * with carry propagation and just return an error instead. We can
- * change that it we even need to draw more blinding values.
- */
- ctx->buf[3] += 1;
- if( ctx->buf[3] == 0 )
- return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
-
- ret = HASH_FUNC( ctx->buf, ctx->total_len, tmp );
- if( ret != 0 )
- return( ret );
-
- if( output_len - len_done > HASH_BLOCK_BYTES )
- use_len = HASH_BLOCK_BYTES;
- else
- use_len = output_len - len_done;
-
- memcpy( output + len_done, tmp, use_len );
- len_done += use_len;
- }
-
- mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
-
- return( 0 );
-}
-
-#else /* DRBG/SHA modules */
+#else
#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
-#endif /* DRBG/SHA modules */
+#endif /* DRBG modules */
#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
#if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -623,39 +502,10 @@ int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp,
#endif /* MBEDTLS_ECP_RESTARTABLE */
-#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
-#define ECP_SHORTWEIERSTRASS
-#endif
-
-#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
- defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
-#define ECP_MONTGOMERY
-#endif
-
-/*
- * Curve types: internal for now, might be exposed later
- */
-typedef enum
-{
- ECP_TYPE_NONE = 0,
- ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
- ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
-} ecp_curve_type;
-
/*
* List of supported curves:
* - internal ID
- * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2)
+ * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2, RFC 8446 sec. 4.2.7)
* - size in bits
* - readable name
*
@@ -699,6 +549,12 @@ static const mbedtls_ecp_curve_info ecp_supported_curves[] =
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
{ MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" },
#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+ { MBEDTLS_ECP_DP_CURVE25519, 29, 256, "x25519" },
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+ { MBEDTLS_ECP_DP_CURVE448, 30, 448, "x448" },
+#endif
{ MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
};
@@ -801,15 +657,15 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name
/*
* Get the type of a curve
*/
-static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
+mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp )
{
if( grp->G.X.p == NULL )
- return( ECP_TYPE_NONE );
+ return( MBEDTLS_ECP_TYPE_NONE );
if( grp->G.Y.p == NULL )
- return( ECP_TYPE_MONTGOMERY );
+ return( MBEDTLS_ECP_TYPE_MONTGOMERY );
else
- return( ECP_TYPE_SHORT_WEIERSTRASS );
+ return( MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS );
}
/*
@@ -920,7 +776,7 @@ void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key )
*/
int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( P != NULL );
ECP_VALIDATE_RET( Q != NULL );
@@ -948,7 +804,7 @@ int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src
*/
int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( pt != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) );
@@ -994,7 +850,7 @@ int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
const char *x, const char *y )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( P != NULL );
ECP_VALIDATE_RET( x != NULL );
ECP_VALIDATE_RET( y != NULL );
@@ -1008,14 +864,14 @@ cleanup:
}
/*
- * Export a point into unsigned binary data (SEC1 2.3.3)
+ * Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748)
*/
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
const mbedtls_ecp_point *P,
int format, size_t *olen,
unsigned char *buf, size_t buflen )
{
- int ret = 0;
+ int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
size_t plen;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( P != NULL );
@@ -1024,56 +880,72 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
format == MBEDTLS_ECP_PF_COMPRESSED );
- /*
- * Common case: P == 0
- */
- if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
- {
- if( buflen < 1 )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
-
- buf[0] = 0x00;
- *olen = 1;
-
- return( 0 );
- }
-
plen = mbedtls_mpi_size( &grp->P );
- if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ (void) format; /* Montgomery curves always use the same point format */
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
- *olen = 2 * plen + 1;
-
+ *olen = plen;
if( buflen < *olen )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- buf[0] = 0x04;
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &P->X, buf, plen ) );
}
- else if( format == MBEDTLS_ECP_PF_COMPRESSED )
+#endif
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
- *olen = plen + 1;
+ /*
+ * Common case: P == 0
+ */
+ if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
+ {
+ if( buflen < 1 )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- if( buflen < *olen )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+ buf[0] = 0x00;
+ *olen = 1;
- buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ return( 0 );
+ }
+
+ if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
+ {
+ *olen = 2 * plen + 1;
+
+ if( buflen < *olen )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+ buf[0] = 0x04;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
+ }
+ else if( format == MBEDTLS_ECP_PF_COMPRESSED )
+ {
+ *olen = plen + 1;
+
+ if( buflen < *olen )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+ buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ }
}
+#endif
cleanup:
return( ret );
}
/*
- * Import a point from unsigned binary data (SEC1 2.3.4)
+ * Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748)
*/
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt,
const unsigned char *buf, size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
size_t plen;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( pt != NULL );
@@ -1082,25 +954,47 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
if( ilen < 1 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( buf[0] == 0x00 )
+ plen = mbedtls_mpi_size( &grp->P );
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
- if( ilen == 1 )
- return( mbedtls_ecp_set_zero( pt ) );
- else
+ if( plen != ilen )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- plen = mbedtls_mpi_size( &grp->P );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &pt->X, buf, plen ) );
+ mbedtls_mpi_free( &pt->Y );
- if( buf[0] != 0x04 )
- return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+ if( grp->id == MBEDTLS_ECP_DP_CURVE25519 )
+ /* Set most significant bit to 0 as prescribed in RFC7748 §5 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &pt->X, plen * 8 - 1, 0 ) );
- if( ilen != 2 * plen + 1 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ }
+#endif
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ {
+ if( buf[0] == 0x00 )
+ {
+ if( ilen == 1 )
+ return( mbedtls_ecp_set_zero( pt ) );
+ else
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ }
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ if( buf[0] != 0x04 )
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+
+ if( ilen != 2 * plen + 1 )
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y,
+ buf + 1 + plen, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ }
+#endif
cleanup:
return( ret );
@@ -1152,7 +1046,7 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp
int format, size_t *olen,
unsigned char *buf, size_t blen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( pt != NULL );
ECP_VALIDATE_RET( olen != NULL );
@@ -1185,7 +1079,7 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp
int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp,
const unsigned char **buf, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group_id grp_id;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( buf != NULL );
@@ -1266,8 +1160,7 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
/*
* Next two bytes are the namedcurve value
*/
- buf[0] = curve_info->tls_id >> 8;
- buf[1] = curve_info->tls_id & 0xFF;
+ MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, buf, 0 );
return( 0 );
}
@@ -1280,7 +1173,7 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
*/
static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( grp->modp == NULL )
return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) );
@@ -1332,6 +1225,18 @@ cleanup:
INC_MUL_COUNT \
} while( 0 )
+static inline int mbedtls_mpi_mul_mod( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *X,
+ const mbedtls_mpi *A,
+ const mbedtls_mpi *B )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( X, A, B ) );
+ MOD_MUL( *X );
+cleanup:
+ return( ret );
+}
+
/*
* Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
* N->s < 0 is a very fast test, which fails only if N is 0
@@ -1340,6 +1245,26 @@ cleanup:
while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 ) \
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) )
+#if ( defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \
+ !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
+ defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \
+ defined(MBEDTLS_ECP_ADD_MIXED_ALT) ) ) || \
+ ( defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) && \
+ !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
+ defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) ) )
+static inline int mbedtls_mpi_sub_mod( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *X,
+ const mbedtls_mpi *A,
+ const mbedtls_mpi *B )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( X, A, B ) );
+ MOD_SUB( *X );
+cleanup:
+ return( ret );
+}
+#endif /* All functions referencing mbedtls_mpi_sub_mod() are alt-implemented without fallback */
+
/*
* Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int.
* We known P, N and the result are positive, so sub_abs is correct, and
@@ -1349,7 +1274,35 @@ cleanup:
while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) )
-#if defined(ECP_SHORTWEIERSTRASS)
+static inline int mbedtls_mpi_add_mod( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *X,
+ const mbedtls_mpi *A,
+ const mbedtls_mpi *B )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, A, B ) );
+ MOD_ADD( *X );
+cleanup:
+ return( ret );
+}
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \
+ !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
+ defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \
+ defined(MBEDTLS_ECP_ADD_MIXED_ALT) )
+static inline int mbedtls_mpi_shift_l_mod( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *X,
+ size_t count )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( X, count ) );
+ MOD_ADD( *X );
+cleanup:
+ return( ret );
+}
+#endif /* All functions referencing mbedtls_mpi_shift_l_mod() are alt-implemented without fallback */
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* For curves in short Weierstrass form, we do all the internal operations in
* Jacobian coordinates.
@@ -1364,9 +1317,6 @@ cleanup:
*/
static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt )
{
- int ret;
- mbedtls_mpi Zi, ZZi;
-
if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 )
return( 0 );
@@ -1375,20 +1325,25 @@ static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p
return( mbedtls_internal_ecp_normalize_jac( grp, pt ) );
#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi Zi, ZZi;
mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
/*
* X = X / Z^2 mod p
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi, &Zi, &Zi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X, &pt->X, &ZZi ) );
/*
* Y = Y / Z^3 mod p
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &ZZi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &Zi ) );
/*
* Z = 1
@@ -1400,6 +1355,7 @@ cleanup:
mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) */
}
/*
@@ -1416,10 +1372,6 @@ cleanup:
static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *T[], size_t T_size )
{
- int ret;
- size_t i;
- mbedtls_mpi *c, u, Zi, ZZi;
-
if( T_size < 2 )
return( ecp_normalize_jac( grp, *T ) );
@@ -1428,6 +1380,13 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
return( mbedtls_internal_ecp_normalize_jac_many( grp, T, T_size ) );
#endif
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t i;
+ mbedtls_mpi *c, u, Zi, ZZi;
+
if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL )
return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
@@ -1442,8 +1401,7 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) );
for( i = 1; i < T_size; i++ )
{
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) );
- MOD_MUL( c[i] );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &c[i], &c[i-1], &T[i]->Z ) );
}
/*
@@ -1462,17 +1420,17 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
}
else
{
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Zi, &u, &c[i-1] ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &u, &u, &T[i]->Z ) );
}
/*
* proceed as in normalize()
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi, &Zi, &Zi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->X, &T[i]->X, &ZZi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &ZZi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &Zi ) );
/*
* Post-precessing: reclaim some memory by shrinking coordinates
@@ -1496,6 +1454,7 @@ cleanup:
mbedtls_free( c );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) */
}
/*
@@ -1506,7 +1465,7 @@ static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *Q,
unsigned char inv )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char nonzero;
mbedtls_mpi mQY;
@@ -1540,9 +1499,6 @@ cleanup:
static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_ecp_point *P )
{
- int ret;
- mbedtls_mpi M, S, T, U;
-
#if defined(MBEDTLS_SELF_TEST)
dbl_count++;
#endif
@@ -1552,58 +1508,64 @@ static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( mbedtls_internal_ecp_double_jac( grp, R, P ) );
#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi M, S, T, U;
+
mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U );
/* Special case for A = -3 */
if( grp->A.p == NULL )
{
/* M = 3(X + Z^2)(X - Z^2) */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->Z, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &T, &P->X, &S ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &U, &P->X, &S ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &T, &U ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
}
else
{
/* M = 3.X^2 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->X, &P->X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
/* Optimize away for "koblitz" curves with A = 0 */
if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 )
{
/* M += A.Z^4 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->Z, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &S, &S ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &T, &grp->A ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &M, &M, &S ) );
}
}
/* S = 4.X.Y^2 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &P->Y, &P->Y ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T, 1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->X, &T ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &S, 1 ) );
/* U = 8.Y^4 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U, &T, &T ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U, 1 ) );
/* T = M^2 - 2.S */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &M, &M ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T, &T, &S ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T, &T, &S ) );
/* S = M(S - T) - U */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S, &S, &T ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &S, &M ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S, &S, &U ) );
/* U = 2.Y.Z */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U, &P->Y, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) );
@@ -1613,6 +1575,7 @@ cleanup:
mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) */
}
/*
@@ -1636,9 +1599,6 @@ cleanup:
static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
{
- int ret;
- mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
-
#if defined(MBEDTLS_SELF_TEST)
add_count++;
#endif
@@ -1648,6 +1608,12 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( mbedtls_internal_ecp_add_mixed( grp, R, P, Q ) );
#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_ADD_MIXED_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
+
/*
* Trivial cases: P == 0 or Q == 0 (case 1)
*/
@@ -1666,12 +1632,12 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1, &P->Z, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2, &T1, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1, &T1, &Q->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2, &T2, &Q->Y ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T1, &T1, &P->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T2, &T2, &P->Y ) );
/* Special cases (2) and (3) */
if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 )
@@ -1688,18 +1654,19 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
}
}
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Z, &P->Z, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T1, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4, &T3, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T3, &P->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &T3 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T1, 1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &X, &T2, &T2 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X, &X, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X, &X, &T4 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T3, &T3, &X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T3, &T2 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4, &T4, &P->Y ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &Y, &T3, &T4 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
@@ -1711,6 +1678,7 @@ cleanup:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_ADD_MIXED_ALT) */
}
/*
@@ -1723,49 +1691,40 @@ cleanup:
static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret;
- mbedtls_mpi l, ll;
- size_t p_size;
- int count = 0;
-
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
if( mbedtls_internal_ecp_grp_capable( grp ) )
return( mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ) );
#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */
- p_size = ( grp->pbits + 7 ) / 8;
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi l, ll;
+
mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll );
/* Generate l such that 1 < l < p */
- do
- {
- if( count++ > 30 )
- {
- ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
- goto cleanup;
- }
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, ( p_size * 8 ) - grp->pbits ) );
- }
- while( ( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ) ||
- ( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
/* Z = l * Z */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Z, &pt->Z, &l ) );
/* X = l^2 * X */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll, &l, &l ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X, &pt->X, &ll ) );
/* Y = l^3 * Y */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll, &ll, &l ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &ll ) );
cleanup:
mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
+ if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+ ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) */
}
/*
@@ -1897,7 +1856,7 @@ static int ecp_precompute_comb( const mbedtls_ecp_group *grp,
unsigned char w, size_t d,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char i;
size_t j = 0;
const unsigned char T_size = 1U << ( w - 1 );
@@ -2033,7 +1992,7 @@ static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_ecp_point T[], unsigned char T_size,
unsigned char i )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char ii, j;
/* Ignore the "sign" bit and scale down */
@@ -2066,7 +2025,7 @@ static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point Txi;
size_t i;
@@ -2148,7 +2107,7 @@ static int ecp_comb_recode_scalar( const mbedtls_ecp_group *grp,
unsigned char w,
unsigned char *parity_trick )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi M, mm;
mbedtls_mpi_init( &M );
@@ -2194,7 +2153,7 @@ static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp,
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char parity_trick;
unsigned char k[COMB_MAX_D + 1];
mbedtls_ecp_point *RR = R;
@@ -2276,8 +2235,10 @@ static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp,
* Make sure w is within bounds.
* (The last test is useful only for very small curves in the test suite.)
*/
+#if( MBEDTLS_ECP_WINDOW_SIZE < 6 )
if( w > MBEDTLS_ECP_WINDOW_SIZE )
w = MBEDTLS_ECP_WINDOW_SIZE;
+#endif
if( w >= grp->nbits )
w = 2;
@@ -2303,7 +2264,7 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char w, p_eq_g, i;
size_t d;
unsigned char T_size = 0, T_ok = 0;
@@ -2455,9 +2416,9 @@ cleanup:
return( ret );
}
-#endif /* ECP_SHORTWEIERSTRASS */
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
-#if defined(ECP_MONTGOMERY)
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
/*
* For Montgomery curves, we do all the internal arithmetic in projective
* coordinates. Import/export of points uses only the x coordinates, which is
@@ -2472,19 +2433,22 @@ cleanup:
*/
static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P )
{
- int ret;
-
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
if( mbedtls_internal_ecp_grp_capable( grp ) )
return( mbedtls_internal_ecp_normalize_mxz( grp, P ) );
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &P->Z ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
cleanup:
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) */
}
/*
@@ -2498,41 +2462,31 @@ cleanup:
static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret;
- mbedtls_mpi l;
- size_t p_size;
- int count = 0;
-
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
if( mbedtls_internal_ecp_grp_capable( grp ) )
return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ) );
#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */
- p_size = ( grp->pbits + 7 ) / 8;
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi l;
mbedtls_mpi_init( &l );
/* Generate l such that 1 < l < p */
- do
- {
- if( count++ > 30 )
- {
- ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
- goto cleanup;
- }
+ MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, ( p_size * 8 ) - grp->pbits ) );
- }
- while( ( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ) ||
- ( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) );
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &l ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->Z, &P->Z, &l ) );
cleanup:
mbedtls_mpi_free( &l );
+ if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+ ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) */
}
/*
@@ -2555,36 +2509,39 @@ static int ecp_double_add_mxz( const mbedtls_ecp_group *grp,
const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
const mbedtls_mpi *d )
{
- int ret;
- mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
-
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
if( mbedtls_internal_ecp_grp_capable( grp ) )
return( mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ) );
#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
+
mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B );
mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C );
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &A, &P->X, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &AA, &A, &A ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &B, &P->X, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &BB, &B, &B ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &E, &AA, &BB ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &C, &Q->X, &Q->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &D, &Q->X, &Q->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &DA, &D, &A ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &CB, &C, &B ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &S->X, &DA, &CB ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->X, &S->X, &S->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S->Z, &DA, &CB ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, &S->Z, &S->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, d, &S->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->X, &AA, &BB ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &grp->A, &E ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &R->Z, &BB, &R->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &E, &R->Z ) );
cleanup:
mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B );
@@ -2592,6 +2549,7 @@ cleanup:
mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) */
}
/*
@@ -2603,7 +2561,7 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
unsigned char b;
mbedtls_ecp_point RP;
@@ -2690,7 +2648,7 @@ cleanup:
return( ret );
}
-#endif /* ECP_MONTGOMERY */
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
/*
* Restartable multiplication R = m * P
@@ -2713,6 +2671,8 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
/* reset ops count for this call if top-level */
if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
rs_ctx->ops_done = 0;
+#else
+ (void) rs_ctx;
#endif
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
@@ -2734,12 +2694,12 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
}
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
-#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
#endif
-#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
#endif
@@ -2772,14 +2732,14 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) );
}
-#if defined(ECP_SHORTWEIERSTRASS)
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* Check that an affine point is valid as a public key,
* short weierstrass curves (SEC1 3.2.3.1)
*/
static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi YY, RHS;
/* pt coordinates must be normalized for our checks */
@@ -2795,8 +2755,8 @@ static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_
* YY = Y^2
* RHS = X (X^2 + A) + B = X^3 + A X + B
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &YY, &pt->Y, &pt->Y ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &pt->X, &pt->X ) );
/* Special case for A = -3 */
if( grp->A.p == NULL )
@@ -2805,11 +2765,11 @@ static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_
}
else
{
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS, &grp->A ) );
}
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &RHS, &pt->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS, &grp->B ) );
if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 )
ret = MBEDTLS_ERR_ECP_INVALID_KEY;
@@ -2820,10 +2780,11 @@ cleanup:
return( ret );
}
-#endif /* ECP_SHORTWEIERSTRASS */
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
- * R = m * P with shortcuts for m == 1 and m == -1
+ * R = m * P with shortcuts for m == 0, m == 1 and m == -1
* NOT constant-time - ONLY for short Weierstrass!
*/
static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
@@ -2832,9 +2793,13 @@ static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *P,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
+ if( mbedtls_mpi_cmp_int( m, 0 ) == 0 )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_ecp_set_zero( R ) );
+ }
+ else if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
{
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
}
@@ -2864,7 +2829,7 @@ int mbedtls_ecp_muladd_restartable(
const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point mP;
mbedtls_ecp_point *pmP = &mP;
mbedtls_ecp_point *pR = R;
@@ -2878,7 +2843,7 @@ int mbedtls_ecp_muladd_restartable(
ECP_VALIDATE_RET( n != NULL );
ECP_VALIDATE_RET( Q != NULL );
- if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
+ if( mbedtls_ecp_get_type( grp ) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
mbedtls_ecp_point_init( &mP );
@@ -2967,8 +2932,9 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
ECP_VALIDATE_RET( Q != NULL );
return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) );
}
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
-#if defined(ECP_MONTGOMERY)
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
#define ECP_MPI_INIT_ARRAY(x) \
@@ -3079,7 +3045,7 @@ static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_
return( ecp_check_bad_points_mx( &pt->X, &grp->P, grp->id ) );
}
-#endif /* ECP_MONTGOMERY */
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
/*
* Check that a point is valid as a public key
@@ -3094,12 +3060,12 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
return( MBEDTLS_ERR_ECP_INVALID_KEY );
-#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
return( ecp_check_pubkey_mx( grp, pt ) );
#endif
-#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
return( ecp_check_pubkey_sw( grp, pt ) );
#endif
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -3114,8 +3080,8 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( d != NULL );
-#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
/* see RFC 7748 sec. 5 para. 5 */
if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
@@ -3129,9 +3095,9 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
return( 0 );
}
-#endif /* ECP_MONTGOMERY */
-#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
/* see SEC1 3.2 */
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
@@ -3140,11 +3106,61 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
else
return( 0 );
}
-#endif /* ECP_SHORTWEIERSTRASS */
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
}
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+MBEDTLS_STATIC_TESTABLE
+int mbedtls_ecp_gen_privkey_mx( size_t high_bit,
+ mbedtls_mpi *d,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+ size_t n_random_bytes = high_bit / 8 + 1;
+
+ /* [Curve25519] page 5 */
+ /* Generate a (high_bit+1)-bit random number by generating just enough
+ * random bytes, then shifting out extra bits from the top (necessary
+ * when (high_bit+1) is not a multiple of 8). */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_random_bytes,
+ f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_random_bytes - high_bit - 1 ) );
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, high_bit, 1 ) );
+
+ /* Make sure the last two bits are unset for Curve448, three bits for
+ Curve25519 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
+ if( high_bit == 254 )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
+ }
+
+cleanup:
+ return( ret );
+}
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+static int mbedtls_ecp_gen_privkey_sw(
+ const mbedtls_mpi *N, mbedtls_mpi *d,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+ int ret = mbedtls_mpi_random( d, 1, N, f_rng, p_rng );
+ switch( ret )
+ {
+ case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
+ return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
+ default:
+ return( ret );
+ }
+}
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
+
/*
* Generate a private key
*/
@@ -3153,97 +3169,21 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- size_t n_size;
-#if defined(ECP_SHORTWEIERSTRASS)
- mbedtls_mpi one;
-
- mbedtls_mpi_init( &one );
-#endif
-
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( d != NULL );
ECP_VALIDATE_RET( f_rng != NULL );
- n_size = ( grp->nbits + 7 ) / 8;
-
-#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
- {
- /* [M225] page 5 */
- size_t b;
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ return( mbedtls_ecp_gen_privkey_mx( grp->nbits, d, f_rng, p_rng ) );
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
- do {
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
- } while( mbedtls_mpi_bitlen( d ) == 0);
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ return( mbedtls_ecp_gen_privkey_sw( &grp->N, d, f_rng, p_rng ) );
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
- /* Make sure the most significant bit is nbits */
- b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
- if( b > grp->nbits )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
- else
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
-
- /* Make sure the last two bits are unset for Curve448, three bits for
- Curve25519 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
- if( grp->nbits == 254 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
- }
- }
-#endif /* ECP_MONTGOMERY */
-
-#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
- {
- /* SEC1 3.2.1: Generate d such that 1 <= n < N */
- int count = 0;
- unsigned lt_lower = 1, lt_upper = 0;
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &one, grp->N.n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
-
- /*
- * Match the procedure given in RFC 6979 (deterministic ECDSA):
- * - use the same byte ordering;
- * - keep the leftmost nbits bits of the generated octet string;
- * - try until result is in the desired range.
- * This also avoids any biais, which is especially important for ECDSA.
- */
- do
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
-
- /*
- * Each try has at worst a probability 1/2 of failing (the msb has
- * a probability 1/2 of being 0, and then the result will be < N),
- * so after 30 tries failure probability is a most 2**(-30).
- *
- * For most curves, 1 try is enough with overwhelming probability,
- * since N starts with a lot of 1s in binary, but some curves
- * such as secp224k1 are actually very close to the worst case.
- */
- if( ++count > 30 )
- {
- ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
- goto cleanup;
- }
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &grp->N, &lt_upper ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &one, &lt_lower ) );
- }
- while( lt_lower != 0 || lt_upper == 0 );
- }
-#endif /* ECP_SHORTWEIERSTRASS */
-
-cleanup:
-#if defined(ECP_SHORTWEIERSTRASS)
- mbedtls_mpi_free( &one );
-#endif
- return( ret );
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
}
/*
@@ -3255,7 +3195,7 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( d != NULL );
ECP_VALIDATE_RET( G != NULL );
@@ -3291,7 +3231,7 @@ int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( key != NULL );
ECP_VALIDATE_RET( f_rng != NULL );
@@ -3301,12 +3241,120 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
}
+#define ECP_CURVE25519_KEY_SIZE 32
+/*
+ * Read a private key.
+ */
+int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
+ const unsigned char *buf, size_t buflen )
+{
+ int ret = 0;
+
+ ECP_VALIDATE_RET( key != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+
+ if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
+ return( ret );
+
+ ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ {
+ /*
+ * If it is Curve25519 curve then mask the key as mandated by RFC7748
+ */
+ if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
+ {
+ if( buflen != ECP_CURVE25519_KEY_SIZE )
+ return MBEDTLS_ERR_ECP_INVALID_KEY;
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) );
+
+ /* Set the three least significant bits to 0 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) );
+
+ /* Set the most significant bit to 0 */
+ MBEDTLS_MPI_CHK(
+ mbedtls_mpi_set_bit( &key->d,
+ ECP_CURVE25519_KEY_SIZE * 8 - 1, 0 )
+ );
+
+ /* Set the second most significant bit to 1 */
+ MBEDTLS_MPI_CHK(
+ mbedtls_mpi_set_bit( &key->d,
+ ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 )
+ );
+ }
+ else
+ ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+ }
+
+#endif
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) );
+
+ MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( &key->grp, &key->d ) );
+ }
+
+#endif
+cleanup:
+
+ if( ret != 0 )
+ mbedtls_mpi_free( &key->d );
+
+ return( ret );
+}
+
+/*
+ * Write a private key.
+ */
+int mbedtls_ecp_write_key( mbedtls_ecp_keypair *key,
+ unsigned char *buf, size_t buflen )
+{
+ int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+
+ ECP_VALIDATE_RET( key != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ {
+ if( key->grp.id == MBEDTLS_ECP_DP_CURVE25519 )
+ {
+ if( buflen < ECP_CURVE25519_KEY_SIZE )
+ return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &key->d, buf, buflen ) );
+ }
+ else
+ ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+ }
+
+#endif
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &key->d, buf, buflen ) );
+ }
+
+#endif
+cleanup:
+
+ return( ret );
+}
+
+
/*
* Check a public-private key pair
*/
int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point Q;
mbedtls_ecp_group grp;
ECP_VALIDATE_RET( pub != NULL );
@@ -3347,103 +3395,141 @@ cleanup:
#if defined(MBEDTLS_SELF_TEST)
-#if defined(ECP_ONE_STEP_KDF)
-/*
- * There are no test vectors from NIST for the One-Step KDF in SP 800-56C,
- * but unofficial ones can be found at:
- * https://github.com/patrickfav/singlestep-kdf/wiki/NIST-SP-800-56C-Rev1:-Non-Official-Test-Vectors
- *
- * We only use the ones with empty fixedInfo, and for brevity's sake, only
- * 40-bytes output (with SHA-256 that's more than one block, and with SHA-512
- * less than one block).
- */
-#if defined(MBEDTLS_SHA512_C)
-
-static const uint8_t test_kdf_z[16] = {
- 0x3b, 0xa9, 0x79, 0xe9, 0xbc, 0x5e, 0x3e, 0xc7,
- 0x61, 0x30, 0x36, 0xb6, 0xf5, 0x1c, 0xd5, 0xaa,
-};
-static const uint8_t test_kdf_out[40] = {
- 0x3e, 0xf6, 0xda, 0xf9, 0x51, 0x60, 0x70, 0x5f,
- 0xdf, 0x21, 0xcd, 0xab, 0xac, 0x25, 0x7b, 0x05,
- 0xfe, 0xc1, 0xab, 0x7c, 0xc9, 0x68, 0x43, 0x25,
- 0x8a, 0xfc, 0x40, 0x6e, 0x5b, 0xf7, 0x98, 0x27,
- 0x10, 0xfa, 0x7b, 0x93, 0x52, 0xd4, 0x16, 0xaa,
-};
-
-#elif defined(MBEDTLS_SHA256_C)
-
-static const uint8_t test_kdf_z[16] = {
- 0xc8, 0x3e, 0x35, 0x8e, 0x99, 0xa6, 0x89, 0xc6,
- 0x7d, 0xb4, 0xfe, 0x39, 0xcf, 0x8f, 0x26, 0xe1,
-};
-static const uint8_t test_kdf_out[40] = {
- 0x7d, 0xf6, 0x41, 0xf8, 0x3c, 0x47, 0xdc, 0x28,
- 0x5f, 0x7f, 0xaa, 0xde, 0x05, 0x64, 0xd6, 0x25,
- 0x00, 0x6a, 0x47, 0xd9, 0x1e, 0xa4, 0xa0, 0x8c,
- 0xd7, 0xf7, 0x0c, 0x99, 0xaa, 0xa0, 0x72, 0x66,
- 0x69, 0x0e, 0x25, 0xaa, 0xa1, 0x63, 0x14, 0x79,
-};
-
+/* Adjust the exponent to be a valid private point for the specified curve.
+ * This is sometimes necessary because we use a single set of exponents
+ * for all curves but the validity of values depends on the curve. */
+static int self_test_adjust_exponent( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *m )
+{
+ int ret = 0;
+ switch( grp->id )
+ {
+ /* If Curve25519 is available, then that's what we use for the
+ * Montgomery test, so we don't need the adjustment code. */
+#if ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+ case MBEDTLS_ECP_DP_CURVE448:
+ /* Move highest bit from 254 to N-1. Setting bit N-1 is
+ * necessary to enforce the highest-bit-set constraint. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( m, 254, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( m, grp->nbits, 1 ) );
+ /* Copy second-highest bit from 253 to N-2. This is not
+ * necessary but improves the test variety a bit. */
+ MBEDTLS_MPI_CHK(
+ mbedtls_mpi_set_bit( m, grp->nbits - 1,
+ mbedtls_mpi_get_bit( m, 253 ) ) );
+ break;
#endif
+#endif /* ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) */
+ default:
+ /* Non-Montgomery curves and Curve25519 need no adjustment. */
+ (void) grp;
+ (void) m;
+ goto cleanup;
+ }
+cleanup:
+ return( ret );
+}
-static int ecp_kdf_self_test( void )
+/* Calculate R = m.P for each m in exponents. Check that the number of
+ * basic operations doesn't depend on the value of m. */
+static int self_test_point( int verbose,
+ mbedtls_ecp_group *grp,
+ mbedtls_ecp_point *R,
+ mbedtls_mpi *m,
+ const mbedtls_ecp_point *P,
+ const char *const *exponents,
+ size_t n_exponents )
{
- int ret;
- ecp_drbg_context kdf_ctx;
- mbedtls_mpi scalar;
- uint8_t out[sizeof( test_kdf_out )];
-
- ecp_drbg_init( &kdf_ctx );
- mbedtls_mpi_init( &scalar );
- memset( out, 0, sizeof( out ) );
+ int ret = 0;
+ size_t i = 0;
+ unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
+ add_count = 0;
+ dbl_count = 0;
+ mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &scalar,
- test_kdf_z, sizeof( test_kdf_z ) ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[0] ) );
+ MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
- MBEDTLS_MPI_CHK( ecp_drbg_seed( &kdf_ctx,
- &scalar, sizeof( test_kdf_z ) ) );
+ for( i = 1; i < n_exponents; i++ )
+ {
+ add_c_prev = add_count;
+ dbl_c_prev = dbl_count;
+ mul_c_prev = mul_count;
+ add_count = 0;
+ dbl_count = 0;
+ mul_count = 0;
- MBEDTLS_MPI_CHK( ecp_drbg_random( &kdf_ctx, out, sizeof( out ) ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[i] ) );
+ MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
- if( memcmp( out, test_kdf_out, sizeof( out ) ) != 0 )
- ret = -1;
+ if( add_count != add_c_prev ||
+ dbl_count != dbl_c_prev ||
+ mul_count != mul_c_prev )
+ {
+ ret = 1;
+ break;
+ }
+ }
cleanup:
- ecp_drbg_free( &kdf_ctx );
- mbedtls_mpi_free( &scalar );
-
+ if( verbose != 0 )
+ {
+ if( ret != 0 )
+ mbedtls_printf( "failed (%u)\n", (unsigned int) i );
+ else
+ mbedtls_printf( "passed\n" );
+ }
return( ret );
}
-#endif /* ECP_ONE_STEP_KDF */
/*
* Checkup routine
*/
int mbedtls_ecp_self_test( int verbose )
{
- int ret;
- size_t i;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group grp;
mbedtls_ecp_point R, P;
mbedtls_mpi m;
- unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
- /* exponents especially adapted for secp192r1 */
- const char *exponents[] =
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ /* Exponents especially adapted for secp192k1, which has the lowest
+ * order n of all supported curves (secp192r1 is in a slightly larger
+ * field but the order of its base point is slightly smaller). */
+ const char *sw_exponents[] =
{
"000000000000000000000000000000000000000000000001", /* one */
- "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */
+ "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8C", /* n - 1 */
"5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
"400000000000000000000000000000000000000000000000", /* one and zeros */
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */
"555555555555555555555555555555555555555555555555", /* 101010... */
};
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ const char *m_exponents[] =
+ {
+ /* Valid private values for Curve25519. In a build with Curve448
+ * but not Curve25519, they will be adjusted in
+ * self_test_adjust_exponent(). */
+ "4000000000000000000000000000000000000000000000000000000000000000",
+ "5C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C30",
+ "5715ECCE24583F7A7023C24164390586842E816D7280A49EF6DF4EAE6B280BF8",
+ "41A2B017516F6D254E1F002BCCBADD54BE30F8CEC737A0E912B4963B6BA74460",
+ "5555555555555555555555555555555555555555555555555555555555555550",
+ "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
+ };
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &R );
mbedtls_ecp_point_init( &P );
mbedtls_mpi_init( &m );
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/* Use secp192r1 if available, or any available curve */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) );
@@ -3452,104 +3538,53 @@ int mbedtls_ecp_self_test( int verbose )
#endif
if( verbose != 0 )
- mbedtls_printf( " ECP test #1 (constant op_count, base point G): " );
-
+ mbedtls_printf( " ECP SW test #1 (constant op_count, base point G): " );
/* Do a dummy multiplication first to trigger precomputation */
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
-
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
-
- for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
- {
- add_c_prev = add_count;
- dbl_c_prev = dbl_count;
- mul_c_prev = mul_count;
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
-
- if( add_count != add_c_prev ||
- dbl_count != dbl_c_prev ||
- mul_count != mul_c_prev )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed (%u)\n", (unsigned int) i );
-
- ret = 1;
- goto cleanup;
- }
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
+ ret = self_test_point( verbose,
+ &grp, &R, &m, &grp.G,
+ sw_exponents,
+ sizeof( sw_exponents ) / sizeof( sw_exponents[0] ));
+ if( ret != 0 )
+ goto cleanup;
if( verbose != 0 )
- mbedtls_printf( " ECP test #2 (constant op_count, other point): " );
+ mbedtls_printf( " ECP SW test #2 (constant op_count, other point): " );
/* We computed P = 2G last time, use it */
+ ret = self_test_point( verbose,
+ &grp, &R, &m, &P,
+ sw_exponents,
+ sizeof( sw_exponents ) / sizeof( sw_exponents[0] ));
+ if( ret != 0 )
+ goto cleanup;
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
-
- for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
- {
- add_c_prev = add_count;
- dbl_c_prev = dbl_count;
- mul_c_prev = mul_count;
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
-
- if( add_count != add_c_prev ||
- dbl_count != dbl_c_prev ||
- mul_count != mul_c_prev )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed (%u)\n", (unsigned int) i );
-
- ret = 1;
- goto cleanup;
- }
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
+ mbedtls_ecp_group_free( &grp );
+ mbedtls_ecp_point_free( &R );
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
-#if defined(ECP_ONE_STEP_KDF)
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( verbose != 0 )
- mbedtls_printf( " ECP test #3 (internal KDF): " );
-
- ret = ecp_kdf_self_test();
+ mbedtls_printf( " ECP Montgomery test (constant op_count): " );
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+ MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_CURVE25519 ) );
+#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+ MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_CURVE448 ) );
+#else
+#error "MBEDTLS_ECP_MONTGOMERY_ENABLED is defined, but no curve is supported for self-test"
+#endif
+ ret = self_test_point( verbose,
+ &grp, &R, &m, &grp.G,
+ m_exponents,
+ sizeof( m_exponents ) / sizeof( m_exponents[0] ));
if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
-
- ret = 1;
goto cleanup;
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
-#endif /* ECP_ONE_STEP_KDF */
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
cleanup:
if( ret < 0 && verbose != 0 )
- mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
+ mbedtls_printf( "Unexpected error, return code = %08X\n", (unsigned int) ret );
mbedtls_ecp_group_free( &grp );
mbedtls_ecp_point_free( &R );
diff --git a/thirdparty/mbedtls/library/ecp_curves.c b/thirdparty/mbedtls/library/ecp_curves.c
index afa3b6324e..ff26a18e8f 100644
--- a/thirdparty/mbedtls/library/ecp_curves.c
+++ b/thirdparty/mbedtls/library/ecp_curves.c
@@ -2,13 +2,7 @@
* Elliptic curves over GF(p): curve-specific data and functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,41 +15,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ECP_C)
#include "mbedtls/ecp.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include "mbedtls/bn_mul.h"
+#include "ecp_invasive.h"
+
#include <string.h>
#if !defined(MBEDTLS_ECP_ALT)
@@ -548,6 +520,22 @@ static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
};
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+/* For these curves, we build the group parameters dynamically. */
+#define ECP_LOAD_GROUP
+#endif
+
+#if defined(ECP_LOAD_GROUP)
/*
* Create an MPI from embedded constants
* (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
@@ -598,6 +586,7 @@ static int ecp_group_load( mbedtls_ecp_group *grp,
return( 0 );
}
+#endif /* ECP_LOAD_GROUP */
#if defined(MBEDTLS_ECP_NIST_OPTIM)
/* Forward declarations */
@@ -639,6 +628,7 @@ static int ecp_mod_p224k1( mbedtls_mpi * );
static int ecp_mod_p256k1( mbedtls_mpi * );
#endif
+#if defined(ECP_LOAD_GROUP)
#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
G ## _p, sizeof( G ## _p ), \
G ## _a, sizeof( G ## _a ), \
@@ -654,6 +644,7 @@ static int ecp_mod_p256k1( mbedtls_mpi * );
G ## _gx, sizeof( G ## _gx ), \
G ## _gy, sizeof( G ## _gy ), \
G ## _n, sizeof( G ## _n ) )
+#endif /* ECP_LOAD_GROUP */
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
/* Constants used by ecp_use_curve25519() */
@@ -668,7 +659,7 @@ static const unsigned char curve25519_part_of_n[] = {
*/
static int ecp_use_curve25519( mbedtls_ecp_group *grp )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Actually ( A + 2 ) / 4 */
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve25519_a24 ) );
@@ -717,7 +708,7 @@ static const unsigned char curve448_part_of_n[] = {
static int ecp_use_curve448( mbedtls_ecp_group *grp )
{
mbedtls_mpi Ns;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi_init( &Ns );
@@ -844,7 +835,7 @@ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
default:
- mbedtls_ecp_group_free( grp );
+ grp->id = MBEDTLS_ECP_DP_NONE;
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
}
}
@@ -908,7 +899,7 @@ static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
*/
static int ecp_mod_p192( mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi_uint c = 0;
mbedtls_mpi_uint *p, *end;
@@ -994,25 +985,20 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
#define ADD( j ) add32( &cur, A( j ), &c );
#define SUB( j ) sub32( &cur, A( j ), &c );
+#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
+#define biL (ciL << 3) /* bits in limb */
+
/*
* Helpers for the main 'loop'
- * (see fix_negative for the motivation of C)
*/
#define INIT( b ) \
- int ret; \
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
signed char c = 0, cc; \
uint32_t cur; \
size_t i = 0, bits = (b); \
- mbedtls_mpi C; \
- mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \
- \
- C.s = 1; \
- C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \
- C.p = Cp; \
- memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \
- \
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \
- sizeof( mbedtls_mpi_uint ) ) ); \
+ /* N is the size of the product of two b-bit numbers, plus one */ \
+ /* limb for fix_negative */ \
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, ( b ) * 2 / biL + 1 ) ); \
LOAD32;
#define NEXT \
@@ -1027,33 +1013,41 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
STORE32; i++; \
cur = c > 0 ? c : 0; STORE32; \
cur = 0; while( ++i < MAX32 ) { STORE32; } \
- if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
+ if( c < 0 ) mbedtls_ecp_fix_negative( N, c, bits );
/*
* If the result is negative, we get it in the form
* c * 2^bits + N, with c negative and N positive shorter than 'bits'
*/
-static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits )
+MBEDTLS_STATIC_TESTABLE
+void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits )
{
- int ret;
-
- /* C = - c * 2^bits */
-#if !defined(MBEDTLS_HAVE_INT64)
- ((void) bits);
-#else
- if( bits == 224 )
- C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
- else
-#endif
- C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
+ size_t i;
- /* N = - ( C - N ) */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
+ /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
+ * set the absolute value to 0xfff...fff - N. There is no carry
+ * since we're subtracting from all-bits-one. */
+ for( i = 0; i <= bits / 8 / sizeof( mbedtls_mpi_uint ); i++ )
+ {
+ N->p[i] = ~(mbedtls_mpi_uint)0 - N->p[i];
+ }
+ /* Add 1, taking care of the carry. */
+ i = 0;
+ do
+ ++N->p[i];
+ while( N->p[i++] == 0 && i <= bits / 8 / sizeof( mbedtls_mpi_uint ) );
+ /* Invert the sign.
+ * Now N = N0 - 2^bits where N0 is the initial value of N. */
N->s = -1;
-cleanup:
-
- return( ret );
+ /* Add |c| * 2^bits to the absolute value. Since c and N are
+ * negative, this adds c * 2^bits. */
+ mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
+#if defined(MBEDTLS_HAVE_INT64)
+ if( bits == 224 )
+ msw <<= 32;
+#endif
+ N->p[bits / 8 / sizeof( mbedtls_mpi_uint)] += msw;
}
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
@@ -1193,7 +1187,7 @@ cleanup:
*/
static int ecp_mod_p521( mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M;
mbedtls_mpi_uint Mp[P521_WIDTH + 1];
@@ -1242,7 +1236,7 @@ cleanup:
*/
static int ecp_mod_p255( mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M;
mbedtls_mpi_uint Mp[P255_WIDTH + 2];
@@ -1299,7 +1293,7 @@ cleanup:
*/
static int ecp_mod_p448( mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M, Q;
mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
@@ -1361,7 +1355,7 @@ cleanup:
static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
size_t adjust, size_t shift, mbedtls_mpi_uint mask )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M, R;
mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
diff --git a/thirdparty/mbedtls/library/ecp_invasive.h b/thirdparty/mbedtls/library/ecp_invasive.h
new file mode 100644
index 0000000000..71c7702758
--- /dev/null
+++ b/thirdparty/mbedtls/library/ecp_invasive.h
@@ -0,0 +1,81 @@
+/**
+ * \file ecp_invasive.h
+ *
+ * \brief ECP module: interfaces for invasive testing only.
+ *
+ * The interfaces in this file are intended for testing purposes only.
+ * They SHOULD NOT be made available in library integrations except when
+ * building the library for testing.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBEDTLS_ECP_INVASIVE_H
+#define MBEDTLS_ECP_INVASIVE_H
+
+#include "common.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/ecp.h"
+
+#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_C)
+
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+/* Preconditions:
+ * - bits is a multiple of 64 or is 224
+ * - c is -1 or -2
+ * - 0 <= N < 2^bits
+ * - N has room for bits plus one limb
+ *
+ * Behavior:
+ * Set N to c * 2^bits + old_value_of_N.
+ */
+void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits );
+#endif
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+/** Generate a private key on a Montgomery curve (Curve25519 or Curve448).
+ *
+ * This function implements key generation for the set of secret keys
+ * specified in [Curve25519] p. 5 and in [Curve448]. The resulting value
+ * has the lower bits masked but is not necessarily canonical.
+ *
+ * \note - [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
+ * - [RFC7748] https://tools.ietf.org/html/rfc7748
+ *
+ * \p high_bit The position of the high-order bit of the key to generate.
+ * This is the bit-size of the key minus 1:
+ * 254 for Curve25519 or 447 for Curve448.
+ * \param d The randomly generated key. This is a number of size
+ * exactly \p n_bits + 1 bits, with the least significant bits
+ * masked as specified in [Curve25519] and in [RFC7748] §5.
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context to be passed to \p f_rng.
+ *
+ * \return \c 0 on success.
+ * \return \c MBEDTLS_ERR_ECP_xxx or MBEDTLS_ERR_MPI_xxx on failure.
+ */
+int mbedtls_ecp_gen_privkey_mx( size_t n_bits,
+ mbedtls_mpi *d,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
+
+#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */
+
+#endif /* MBEDTLS_ECP_INVASIVE_H */
diff --git a/thirdparty/mbedtls/library/entropy.c b/thirdparty/mbedtls/library/entropy.c
index 9f1a32bdc1..12fd3b9b5f 100644
--- a/thirdparty/mbedtls/library/entropy.c
+++ b/thirdparty/mbedtls/library/entropy.c
@@ -2,13 +2,7 @@
* Entropy accumulator implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ENTROPY_C)
@@ -61,6 +30,7 @@
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -266,7 +236,7 @@ cleanup:
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
@@ -288,7 +258,9 @@ int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
*/
static int entropy_gather_internal( mbedtls_entropy_context *ctx )
{
- int ret, i, have_one_strong = 0;
+ int ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+ int i;
+ int have_one_strong = 0;
unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
size_t olen;
@@ -336,7 +308,7 @@ cleanup:
*/
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
@@ -355,7 +327,8 @@ int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
{
- int ret, count = 0, i, done;
+ int ret, count = 0, i, thresholds_reached;
+ size_t strong_size;
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
@@ -393,12 +366,17 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
goto exit;
- done = 1;
+ thresholds_reached = 1;
+ strong_size = 0;
for( i = 0; i < ctx->source_count; i++ )
+ {
if( ctx->source[i].size < ctx->source[i].threshold )
- done = 0;
+ thresholds_reached = 0;
+ if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
+ strong_size += ctx->source[i].size;
+ }
}
- while( ! done );
+ while( ! thresholds_reached || strong_size < MBEDTLS_ENTROPY_BLOCK_SIZE );
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
@@ -493,7 +471,7 @@ int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
#if defined(MBEDTLS_FS_IO)
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
{
- int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
FILE *f = NULL;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c
index 2095a7dd34..40f23fd2a6 100644
--- a/thirdparty/mbedtls/library/entropy_poll.c
+++ b/thirdparty/mbedtls/library/entropy_poll.c
@@ -2,13 +2,7 @@
* Platform-specific and custom entropy polling functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#if defined(__linux__) && !defined(_GNU_SOURCE)
@@ -49,11 +22,7 @@
#define _GNU_SOURCE
#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#include <string.h>
@@ -61,6 +30,7 @@
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_TIMING_C)
#include "mbedtls/timing.h"
@@ -76,7 +46,7 @@
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
- !defined(__HAIKU__)
+ !defined(__HAIKU__) && !defined(__midipix__)
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
#endif
@@ -134,7 +104,7 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len
* Since there is no wrapper in the libc yet, use the generic syscall wrapper
* available in GNU libc and compatible libc's (eg uClibc).
*/
-#if defined(__linux__) && defined(__GLIBC__)
+#if ((defined(__linux__) && defined(__GLIBC__)) || defined(__midipix__))
#include <unistd.h>
#include <sys/syscall.h>
#if defined(SYS_getrandom)
@@ -152,7 +122,57 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
return( syscall( SYS_getrandom, buf, buflen, flags ) );
}
#endif /* SYS_getrandom */
-#endif /* __linux__ */
+#endif /* __linux__ || __midipix__ */
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/param.h>
+#if (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || \
+ (defined(__DragonFly__) && __DragonFly_version >= 500700)
+#include <errno.h>
+#include <sys/random.h>
+#define HAVE_GETRANDOM
+static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
+{
+ return getrandom( buf, buflen, flags );
+}
+#endif /* (__FreeBSD__ && __FreeBSD_version >= 1200000) ||
+ (__DragonFly__ && __DragonFly_version >= 500700) */
+#endif /* __FreeBSD__ || __DragonFly__ */
+
+/*
+ * Some BSD systems provide KERN_ARND.
+ * This is equivalent to reading from /dev/urandom, only it doesn't require an
+ * open file descriptor, and provides up to 256 bytes per call (basically the
+ * same as getentropy(), but with a longer history).
+ *
+ * Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7
+ */
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#if defined(KERN_ARND)
+#define HAVE_SYSCTL_ARND
+
+static int sysctl_arnd_wrapper( unsigned char *buf, size_t buflen )
+{
+ int name[2];
+ size_t len;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_ARND;
+
+ while( buflen > 0 )
+ {
+ len = buflen > 256 ? 256 : buflen;
+ if( sysctl(name, 2, buf, &len, NULL, 0) == -1 )
+ return( -1 );
+ buflen -= len;
+ buf += len;
+ }
+ return( 0 );
+}
+#endif /* KERN_ARND */
+#endif /* __FreeBSD__ || __NetBSD__ */
#include <stdio.h>
@@ -161,7 +181,7 @@ int mbedtls_platform_entropy_poll( void *data,
{
FILE *file;
size_t read_len;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
((void) data);
#if defined(HAVE_GETRANDOM)
@@ -178,6 +198,15 @@ int mbedtls_platform_entropy_poll( void *data,
((void) ret);
#endif /* HAVE_GETRANDOM */
+#if defined(HAVE_SYSCTL_ARND)
+ ((void) file);
+ ((void) read_len);
+ if( sysctl_arnd_wrapper( output, len ) == -1 )
+ return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+ *olen = len;
+ return( 0 );
+#else
+
*olen = 0;
file = fopen( "/dev/urandom", "rb" );
@@ -195,6 +224,7 @@ int mbedtls_platform_entropy_poll( void *data,
*olen = len;
return( 0 );
+#endif /* HAVE_SYSCTL_ARND */
}
#endif /* _WIN32 && !EFIX64 && !EFI32 */
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
@@ -205,13 +235,13 @@ int mbedtls_null_entropy_poll( void *data,
{
((void) data);
((void) output);
- *olen = 0;
+ *olen = 0;
if( len < sizeof(unsigned char) )
return( 0 );
+ output[0] = 0;
*olen = sizeof(unsigned char);
-
return( 0 );
}
#endif
diff --git a/thirdparty/mbedtls/library/error.c b/thirdparty/mbedtls/library/error.c
index b83b8d1f1b..afad38904f 100644
--- a/thirdparty/mbedtls/library/error.c
+++ b/thirdparty/mbedtls/library/error.c
@@ -2,13 +2,7 @@
* Error message information
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,39 +15,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+#include "common.h"
#include "mbedtls/error.h"
+#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+
#if defined(MBEDTLS_ERROR_C)
#if defined(MBEDTLS_PLATFORM_C)
@@ -137,6 +106,10 @@
#include "mbedtls/entropy.h"
#endif
+#if defined(MBEDTLS_ERROR_C)
+#include "mbedtls/error.h"
+#endif
+
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#endif
@@ -238,692 +211,751 @@
#endif
-void mbedtls_strerror( int ret, char *buf, size_t buflen )
+const char * mbedtls_high_level_strerr( int error_code )
{
- size_t len;
- int use_ret;
+ int high_level_error_code;
- if( buflen == 0 )
- return;
-
- memset( buf, 0x00, buflen );
+ if( error_code < 0 )
+ error_code = -error_code;
- if( ret < 0 )
- ret = -ret;
+ /* Extract the high-level part from the error code. */
+ high_level_error_code = error_code & 0xFF80;
- if( ret & 0xFF80 )
+ switch( high_level_error_code )
{
- use_ret = ret & 0xFF80;
-
- // High level error codes
- //
- // BEGIN generated code
+ /* Begin Auto-Generated Code. */
#if defined(MBEDTLS_CIPHER_C)
- if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
- mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE):
+ return( "CIPHER - The selected feature is not available" );
+ case -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA):
+ return( "CIPHER - Bad input parameters" );
+ case -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED):
+ return( "CIPHER - Failed to allocate memory" );
+ case -(MBEDTLS_ERR_CIPHER_INVALID_PADDING):
+ return( "CIPHER - Input data contains invalid padding and is rejected" );
+ case -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED):
+ return( "CIPHER - Decryption of block requires a full block" );
+ case -(MBEDTLS_ERR_CIPHER_AUTH_FAILED):
+ return( "CIPHER - Authentication failed (for AEAD modes)" );
+ case -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT):
+ return( "CIPHER - The context is invalid. For example, because it was freed" );
+ case -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED):
+ return( "CIPHER - Cipher hardware accelerator failed" );
#endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_DHM_C)
- if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" );
- if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" );
- if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" );
+ case -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA):
+ return( "DHM - Bad input parameters" );
+ case -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED):
+ return( "DHM - Reading of the DHM parameters failed" );
+ case -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED):
+ return( "DHM - Making of the DHM parameters failed" );
+ case -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED):
+ return( "DHM - Reading of the public values failed" );
+ case -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED):
+ return( "DHM - Making of the public value failed" );
+ case -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED):
+ return( "DHM - Calculation of the DHM secret failed" );
+ case -(MBEDTLS_ERR_DHM_INVALID_FORMAT):
+ return( "DHM - The ASN.1 data is not formatted correctly" );
+ case -(MBEDTLS_ERR_DHM_ALLOC_FAILED):
+ return( "DHM - Allocation of memory failed" );
+ case -(MBEDTLS_ERR_DHM_FILE_IO_ERROR):
+ return( "DHM - Read or write of file failed" );
+ case -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED):
+ return( "DHM - DHM hardware accelerator failed" );
+ case -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED):
+ return( "DHM - Setting the modulus and generator failed" );
#endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_ECP_C)
- if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
- if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "ECP - The requested feature is not available, for example, the requested curve is not supported" );
- if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
- if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as ephemeral key, failed" );
- if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
- mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
- if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
- if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_ECP_IN_PROGRESS) )
- mbedtls_snprintf( buf, buflen, "ECP - Operation in progress, call again with the same parameters to continue" );
+ case -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA):
+ return( "ECP - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL):
+ return( "ECP - The buffer is too small to write to" );
+ case -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE):
+ return( "ECP - The requested feature is not available, for example, the requested curve is not supported" );
+ case -(MBEDTLS_ERR_ECP_VERIFY_FAILED):
+ return( "ECP - The signature is not valid" );
+ case -(MBEDTLS_ERR_ECP_ALLOC_FAILED):
+ return( "ECP - Memory allocation failed" );
+ case -(MBEDTLS_ERR_ECP_RANDOM_FAILED):
+ return( "ECP - Generation of random value, such as ephemeral key, failed" );
+ case -(MBEDTLS_ERR_ECP_INVALID_KEY):
+ return( "ECP - Invalid private or public key" );
+ case -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH):
+ return( "ECP - The buffer contains a valid signature followed by more data" );
+ case -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED):
+ return( "ECP - The ECP hardware accelerator failed" );
+ case -(MBEDTLS_ERR_ECP_IN_PROGRESS):
+ return( "ECP - Operation in progress, call again with the same parameters to continue" );
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C)
- if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
- if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" );
+ case -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE):
+ return( "MD - The selected feature is not available" );
+ case -(MBEDTLS_ERR_MD_BAD_INPUT_DATA):
+ return( "MD - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_MD_ALLOC_FAILED):
+ return( "MD - Failed to allocate memory" );
+ case -(MBEDTLS_ERR_MD_FILE_IO_ERROR):
+ return( "MD - Opening or reading of file failed" );
+ case -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED):
+ return( "MD - MD hardware accelerator failed" );
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
- if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
- mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" );
- if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) )
- mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" );
- if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) )
- mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
- if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) )
- mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
- if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" );
- if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
- if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
- if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT):
+ return( "PEM - No PEM header or footer found" );
+ case -(MBEDTLS_ERR_PEM_INVALID_DATA):
+ return( "PEM - PEM string is not as expected" );
+ case -(MBEDTLS_ERR_PEM_ALLOC_FAILED):
+ return( "PEM - Failed to allocate memory" );
+ case -(MBEDTLS_ERR_PEM_INVALID_ENC_IV):
+ return( "PEM - RSA IV is not in hex-format" );
+ case -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG):
+ return( "PEM - Unsupported key encryption algorithm" );
+ case -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED):
+ return( "PEM - Private key password can't be empty" );
+ case -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH):
+ return( "PEM - Given private key password does not allow for correct decryption" );
+ case -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE):
+ return( "PEM - Unavailable feature, e.g. hashing/encryption combination" );
+ case -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA):
+ return( "PEM - Bad input parameters to function" );
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
#if defined(MBEDTLS_PK_C)
- if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
- if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" );
- if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) )
- mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" );
- if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" );
- if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) )
- mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" );
- if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" );
- if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) )
- mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) )
- mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) )
- mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
- if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" );
- if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" );
+ case -(MBEDTLS_ERR_PK_ALLOC_FAILED):
+ return( "PK - Memory allocation failed" );
+ case -(MBEDTLS_ERR_PK_TYPE_MISMATCH):
+ return( "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
+ case -(MBEDTLS_ERR_PK_BAD_INPUT_DATA):
+ return( "PK - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_PK_FILE_IO_ERROR):
+ return( "PK - Read/write of file failed" );
+ case -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION):
+ return( "PK - Unsupported key version" );
+ case -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT):
+ return( "PK - Invalid key tag or value" );
+ case -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG):
+ return( "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
+ case -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED):
+ return( "PK - Private key password can't be empty" );
+ case -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH):
+ return( "PK - Given private key password does not allow for correct decryption" );
+ case -(MBEDTLS_ERR_PK_INVALID_PUBKEY):
+ return( "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
+ case -(MBEDTLS_ERR_PK_INVALID_ALG):
+ return( "PK - The algorithm tag or value is invalid" );
+ case -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE):
+ return( "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
+ case -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE):
+ return( "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
+ case -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH):
+ return( "PK - The buffer contains a valid signature followed by more data" );
+ case -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED):
+ return( "PK - PK hardware accelerator failed" );
#endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_PKCS12_C)
- if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
+ case -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA):
+ return( "PKCS12 - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE):
+ return( "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
+ case -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT):
+ return( "PKCS12 - PBE ASN.1 data not as expected" );
+ case -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH):
+ return( "PKCS12 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS12_C */
#if defined(MBEDTLS_PKCS5_C)
- if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
+ case -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA):
+ return( "PKCS5 - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT):
+ return( "PKCS5 - Unexpected ASN.1 data" );
+ case -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE):
+ return( "PKCS5 - Requested encryption or digest alg not available" );
+ case -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH):
+ return( "PKCS5 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS5_C */
#if defined(MBEDTLS_RSA_C)
- if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) )
- mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
- if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
- if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" );
- if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) )
- mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
- if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
- if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) )
- mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
- if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" );
+ case -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA):
+ return( "RSA - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_RSA_INVALID_PADDING):
+ return( "RSA - Input data contains invalid padding and is rejected" );
+ case -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED):
+ return( "RSA - Something failed during generation of a key" );
+ case -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED):
+ return( "RSA - Key failed to pass the validity check of the library" );
+ case -(MBEDTLS_ERR_RSA_PUBLIC_FAILED):
+ return( "RSA - The public key operation failed" );
+ case -(MBEDTLS_ERR_RSA_PRIVATE_FAILED):
+ return( "RSA - The private key operation failed" );
+ case -(MBEDTLS_ERR_RSA_VERIFY_FAILED):
+ return( "RSA - The PKCS#1 verification failed" );
+ case -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE):
+ return( "RSA - The output buffer for decryption is not large enough" );
+ case -(MBEDTLS_ERR_RSA_RNG_FAILED):
+ return( "RSA - The random generator failed to generate non-zeros" );
+ case -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION):
+ return( "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
+ case -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED):
+ return( "RSA - RSA hardware accelerator failed" );
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SSL_TLS_C)
- if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) )
- mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) )
- mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) )
- mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) )
- mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) )
- mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) )
- mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) )
- mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) )
- mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
- if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) )
- {
- mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
- return;
- }
- if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) )
- mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
- mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
- if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
- mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) )
- mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) )
- mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) )
- mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
- mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
- mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
- mbedtls_snprintf( buf, buflen, "SSL - No data of requested type currently available on underlying transport" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
- mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
- if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
- mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) )
- mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) )
- mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) )
- mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) )
- mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
- mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
- if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) )
- mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" );
- if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) )
- mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_CONFIG) )
- mbedtls_snprintf( buf, buflen, "SSL - Invalid value in SSL config" );
+ case -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE):
+ return( "SSL - The requested feature is not available" );
+ case -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA):
+ return( "SSL - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_SSL_INVALID_MAC):
+ return( "SSL - Verification of the message MAC failed" );
+ case -(MBEDTLS_ERR_SSL_INVALID_RECORD):
+ return( "SSL - An invalid SSL record was received" );
+ case -(MBEDTLS_ERR_SSL_CONN_EOF):
+ return( "SSL - The connection indicated an EOF" );
+ case -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER):
+ return( "SSL - An unknown cipher was received" );
+ case -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN):
+ return( "SSL - The server has no ciphersuites in common with the client" );
+ case -(MBEDTLS_ERR_SSL_NO_RNG):
+ return( "SSL - No RNG was provided to the SSL module" );
+ case -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE):
+ return( "SSL - No client certification received from the client, but required by the authentication mode" );
+ case -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE):
+ return( "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
+ case -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED):
+ return( "SSL - The own certificate is not set, but needed by the server" );
+ case -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED):
+ return( "SSL - The own private key or pre-shared key is not set, but needed" );
+ case -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED):
+ return( "SSL - No CA Chain is set, but required to operate" );
+ case -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE):
+ return( "SSL - An unexpected message was received from our peer" );
+ case -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE):
+ return( "SSL - A fatal alert message was received from our peer" );
+ case -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED):
+ return( "SSL - Verification of our peer failed" );
+ case -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY):
+ return( "SSL - The peer notified us that the connection is going to be closed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO):
+ return( "SSL - Processing of the ClientHello handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO):
+ return( "SSL - Processing of the ServerHello handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE):
+ return( "SSL - Processing of the Certificate handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST):
+ return( "SSL - Processing of the CertificateRequest handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE):
+ return( "SSL - Processing of the ServerKeyExchange handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE):
+ return( "SSL - Processing of the ServerHelloDone handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE):
+ return( "SSL - Processing of the ClientKeyExchange handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP):
+ return( "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS):
+ return( "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY):
+ return( "SSL - Processing of the CertificateVerify handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC):
+ return( "SSL - Processing of the ChangeCipherSpec handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED):
+ return( "SSL - Processing of the Finished handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_ALLOC_FAILED):
+ return( "SSL - Memory allocation failed" );
+ case -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED):
+ return( "SSL - Hardware acceleration function returned with error" );
+ case -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH):
+ return( "SSL - Hardware acceleration function skipped / left alone data" );
+ case -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED):
+ return( "SSL - Processing of the compression / decompression failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION):
+ return( "SSL - Handshake protocol not within min/max boundaries" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET):
+ return( "SSL - Processing of the NewSessionTicket handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED):
+ return( "SSL - Session ticket has expired" );
+ case -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH):
+ return( "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
+ case -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY):
+ return( "SSL - Unknown identity received (eg, PSK identity)" );
+ case -(MBEDTLS_ERR_SSL_INTERNAL_ERROR):
+ return( "SSL - Internal error (eg, unexpected failure in lower-level module)" );
+ case -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING):
+ return( "SSL - A counter would wrap (eg, too many messages exchanged)" );
+ case -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO):
+ return( "SSL - Unexpected message at ServerHello in renegotiation" );
+ case -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED):
+ return( "SSL - DTLS client must retry for hello verification" );
+ case -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL):
+ return( "SSL - A buffer is too small to receive or write a message" );
+ case -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE):
+ return( "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
+ case -(MBEDTLS_ERR_SSL_WANT_READ):
+ return( "SSL - No data of requested type currently available on underlying transport" );
+ case -(MBEDTLS_ERR_SSL_WANT_WRITE):
+ return( "SSL - Connection requires a write call" );
+ case -(MBEDTLS_ERR_SSL_TIMEOUT):
+ return( "SSL - The operation timed out" );
+ case -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT):
+ return( "SSL - The client initiated a reconnect from the same port" );
+ case -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD):
+ return( "SSL - Record header looks valid but is not expected" );
+ case -(MBEDTLS_ERR_SSL_NON_FATAL):
+ return( "SSL - The alert message received indicates a non-fatal error" );
+ case -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH):
+ return( "SSL - Couldn't set the hash for verifying CertificateVerify" );
+ case -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING):
+ return( "SSL - Internal-only message signaling that further message-processing should be done" );
+ case -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS):
+ return( "SSL - The asynchronous operation is not completed yet" );
+ case -(MBEDTLS_ERR_SSL_EARLY_MESSAGE):
+ return( "SSL - Internal-only message signaling that a message arrived early" );
+ case -(MBEDTLS_ERR_SSL_UNEXPECTED_CID):
+ return( "SSL - An encrypted DTLS-frame with an unexpected CID was received" );
+ case -(MBEDTLS_ERR_SSL_VERSION_MISMATCH):
+ return( "SSL - An operation failed due to an unexpected version or configuration" );
+ case -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS):
+ return( "SSL - A cryptographic operation is in progress. Try again later" );
+ case -(MBEDTLS_ERR_SSL_BAD_CONFIG):
+ return( "SSL - Invalid value in SSL config" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
- if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) )
- mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) )
- mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) )
- mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) )
- mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) )
- mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) )
- mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) )
- mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) )
- mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) )
- mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) )
- mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
- if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
- if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) )
- mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
- if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "X509 - Input invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
- if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) )
- mbedtls_snprintf( buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" );
+ case -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE):
+ return( "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
+ case -(MBEDTLS_ERR_X509_UNKNOWN_OID):
+ return( "X509 - Requested OID is unknown" );
+ case -(MBEDTLS_ERR_X509_INVALID_FORMAT):
+ return( "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
+ case -(MBEDTLS_ERR_X509_INVALID_VERSION):
+ return( "X509 - The CRT/CRL/CSR version element is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_SERIAL):
+ return( "X509 - The serial tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_ALG):
+ return( "X509 - The algorithm tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_NAME):
+ return( "X509 - The name tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_DATE):
+ return( "X509 - The date tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_SIGNATURE):
+ return( "X509 - The signature tag or value invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS):
+ return( "X509 - The extension tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_UNKNOWN_VERSION):
+ return( "X509 - CRT/CRL/CSR has an unsupported version number" );
+ case -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG):
+ return( "X509 - Signature algorithm (oid) is unsupported" );
+ case -(MBEDTLS_ERR_X509_SIG_MISMATCH):
+ return( "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
+ case -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED):
+ return( "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
+ case -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT):
+ return( "X509 - Format not recognized as DER or PEM" );
+ case -(MBEDTLS_ERR_X509_BAD_INPUT_DATA):
+ return( "X509 - Input invalid" );
+ case -(MBEDTLS_ERR_X509_ALLOC_FAILED):
+ return( "X509 - Allocation of memory failed" );
+ case -(MBEDTLS_ERR_X509_FILE_IO_ERROR):
+ return( "X509 - Read/write of file failed" );
+ case -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL):
+ return( "X509 - Destination buffer is too small" );
+ case -(MBEDTLS_ERR_X509_FATAL_ERROR):
+ return( "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" );
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
- // END generated code
+ /* End Auto-Generated Code. */
- if( strlen( buf ) == 0 )
- mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
+ default:
+ break;
}
- use_ret = ret & ~0xFF80;
-
- if( use_ret == 0 )
- return;
-
- // If high level code is present, make a concatenation between both
- // error strings.
- //
- len = strlen( buf );
+ return( NULL );
+}
- if( len > 0 )
- {
- if( buflen - len < 5 )
- return;
+const char * mbedtls_low_level_strerr( int error_code )
+{
+ int low_level_error_code;
- mbedtls_snprintf( buf + len, buflen - len, " : " );
+ if( error_code < 0 )
+ error_code = -error_code;
- buf += len + 3;
- buflen -= len + 3;
- }
+ /* Extract the low-level part from the error code. */
+ low_level_error_code = error_code & ~0xFF80;
- // Low level error codes
- //
- // BEGIN generated code
+ switch( low_level_error_code )
+ {
+ /* Begin Auto-Generated Code. */
#if defined(MBEDTLS_AES_C)
- if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) )
- mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
- if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
- if( use_ret == -(MBEDTLS_ERR_AES_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "AES - Invalid input data" );
- if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
- if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" );
+ case -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH):
+ return( "AES - Invalid key length" );
+ case -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH):
+ return( "AES - Invalid data input length" );
+ case -(MBEDTLS_ERR_AES_BAD_INPUT_DATA):
+ return( "AES - Invalid input data" );
+ case -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE):
+ return( "AES - Feature not available. For example, an unsupported AES key size" );
+ case -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED):
+ return( "AES - AES hardware accelerator failed" );
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_ARC4_C)
- if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED):
+ return( "ARC4 - ARC4 hardware accelerator failed" );
#endif /* MBEDTLS_ARC4_C */
#if defined(MBEDTLS_ARIA_C)
- if( use_ret == -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "ARIA - Bad input data" );
- if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" );
- if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "ARIA - Feature not available. For example, an unsupported ARIA key size" );
- if( use_ret == -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "ARIA - ARIA hardware accelerator failed" );
+ case -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA):
+ return( "ARIA - Bad input data" );
+ case -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH):
+ return( "ARIA - Invalid data input length" );
+ case -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE):
+ return( "ARIA - Feature not available. For example, an unsupported ARIA key size" );
+ case -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED):
+ return( "ARIA - ARIA hardware accelerator failed" );
#endif /* MBEDTLS_ARIA_C */
#if defined(MBEDTLS_ASN1_PARSE_C)
- if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) )
- mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
+ case -(MBEDTLS_ERR_ASN1_OUT_OF_DATA):
+ return( "ASN1 - Out of data when parsing an ASN1 data structure" );
+ case -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG):
+ return( "ASN1 - ASN1 tag was of an unexpected value" );
+ case -(MBEDTLS_ERR_ASN1_INVALID_LENGTH):
+ return( "ASN1 - Error when trying to determine the length or invalid length" );
+ case -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH):
+ return( "ASN1 - Actual length differs from expected length" );
+ case -(MBEDTLS_ERR_ASN1_INVALID_DATA):
+ return( "ASN1 - Data is invalid" );
+ case -(MBEDTLS_ERR_ASN1_ALLOC_FAILED):
+ return( "ASN1 - Memory allocation failed" );
+ case -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL):
+ return( "ASN1 - Buffer too small when writing ASN.1 data structure" );
#endif /* MBEDTLS_ASN1_PARSE_C */
#if defined(MBEDTLS_BASE64_C)
- if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" );
- if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) )
- mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" );
+ case -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL):
+ return( "BASE64 - Output buffer too small" );
+ case -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER):
+ return( "BASE64 - Invalid character in input" );
#endif /* MBEDTLS_BASE64_C */
#if defined(MBEDTLS_BIGNUM_C)
- if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
- if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
- if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
- if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
- if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
- if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
- if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
+ case -(MBEDTLS_ERR_MPI_FILE_IO_ERROR):
+ return( "BIGNUM - An error occurred while reading from or writing to a file" );
+ case -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA):
+ return( "BIGNUM - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_MPI_INVALID_CHARACTER):
+ return( "BIGNUM - There is an invalid character in the digit string" );
+ case -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL):
+ return( "BIGNUM - The buffer is too small to write to" );
+ case -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE):
+ return( "BIGNUM - The input arguments are negative or result in illegal output" );
+ case -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO):
+ return( "BIGNUM - The input argument for division is zero, which is not allowed" );
+ case -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE):
+ return( "BIGNUM - The input arguments are not acceptable" );
+ case -(MBEDTLS_ERR_MPI_ALLOC_FAILED):
+ return( "BIGNUM - Memory allocation failed" );
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_BLOWFISH_C)
- if( use_ret == -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "BLOWFISH - Bad input data" );
- if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
- if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
+ case -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA):
+ return( "BLOWFISH - Bad input data" );
+ case -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH):
+ return( "BLOWFISH - Invalid data input length" );
+ case -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED):
+ return( "BLOWFISH - Blowfish hardware accelerator failed" );
#endif /* MBEDTLS_BLOWFISH_C */
#if defined(MBEDTLS_CAMELLIA_C)
- if( use_ret == -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "CAMELLIA - Bad input data" );
- if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
- if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA):
+ return( "CAMELLIA - Bad input data" );
+ case -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH):
+ return( "CAMELLIA - Invalid data input length" );
+ case -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED):
+ return( "CAMELLIA - Camellia hardware accelerator failed" );
#endif /* MBEDTLS_CAMELLIA_C */
#if defined(MBEDTLS_CCM_C)
- if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
- mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" );
- if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
- if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CCM_BAD_INPUT):
+ return( "CCM - Bad input parameters to the function" );
+ case -(MBEDTLS_ERR_CCM_AUTH_FAILED):
+ return( "CCM - Authenticated decryption failed" );
+ case -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED):
+ return( "CCM - CCM hardware accelerator failed" );
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHA20_C)
- if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" );
- if( use_ret == -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "CHACHA20 - Feature not available. For example, s part of the API is not implemented" );
- if( use_ret == -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CHACHA20 - Chacha20 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA):
+ return( "CHACHA20 - Invalid input parameter(s)" );
+ case -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE):
+ return( "CHACHA20 - Feature not available. For example, s part of the API is not implemented" );
+ case -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED):
+ return( "CHACHA20 - Chacha20 hardware accelerator failed" );
#endif /* MBEDTLS_CHACHA20_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
- if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) )
- mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" );
- if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Authenticated decryption failed: data was not authentic" );
+ case -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE):
+ return( "CHACHAPOLY - The requested operation is not permitted in the current state" );
+ case -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED):
+ return( "CHACHAPOLY - Authenticated decryption failed: data was not authentic" );
#endif /* MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_CMAC_C)
- if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED):
+ return( "CMAC - CMAC hardware accelerator failed" );
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_CTR_DRBG_C)
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" );
+ case -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED):
+ return( "CTR_DRBG - The entropy source failed" );
+ case -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG):
+ return( "CTR_DRBG - The requested random buffer length is too big" );
+ case -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG):
+ return( "CTR_DRBG - The input (entropy + additional data) is too large" );
+ case -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR):
+ return( "CTR_DRBG - Read or write error in file" );
#endif /* MBEDTLS_CTR_DRBG_C */
#if defined(MBEDTLS_DES_C)
- if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
- if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" );
+ case -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH):
+ return( "DES - The data input has an invalid length" );
+ case -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED):
+ return( "DES - DES hardware accelerator failed" );
#endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_ENTROPY_C)
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" );
+ case -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED):
+ return( "ENTROPY - Critical entropy source failure" );
+ case -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES):
+ return( "ENTROPY - No more sources can be added" );
+ case -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED):
+ return( "ENTROPY - No sources have been added to poll" );
+ case -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE):
+ return( "ENTROPY - No strong sources have been added to poll" );
+ case -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR):
+ return( "ENTROPY - Read/write error in file" );
#endif /* MBEDTLS_ENTROPY_C */
+#if defined(MBEDTLS_ERROR_C)
+ case -(MBEDTLS_ERR_ERROR_GENERIC_ERROR):
+ return( "ERROR - Generic error" );
+ case -(MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED):
+ return( "ERROR - This is a bug in the library" );
+#endif /* MBEDTLS_ERROR_C */
+
#if defined(MBEDTLS_GCM_C)
- if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
- if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
- mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_GCM_AUTH_FAILED):
+ return( "GCM - Authenticated decryption failed" );
+ case -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED):
+ return( "GCM - GCM hardware accelerator failed" );
+ case -(MBEDTLS_ERR_GCM_BAD_INPUT):
+ return( "GCM - Bad input parameters to function" );
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_HKDF_C)
- if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA):
+ return( "HKDF - Bad input parameters to function" );
#endif /* MBEDTLS_HKDF_C */
#if defined(MBEDTLS_HMAC_DRBG_C)
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
+ case -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG):
+ return( "HMAC_DRBG - Too many random requested in single call" );
+ case -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG):
+ return( "HMAC_DRBG - Input too large (Entropy + additional)" );
+ case -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR):
+ return( "HMAC_DRBG - Read/write error in file" );
+ case -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED):
+ return( "HMAC_DRBG - The entropy source failed" );
#endif /* MBEDTLS_HMAC_DRBG_C */
#if defined(MBEDTLS_MD2_C)
- if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED):
+ return( "MD2 - MD2 hardware accelerator failed" );
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
- if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED):
+ return( "MD4 - MD4 hardware accelerator failed" );
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
- if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED):
+ return( "MD5 - MD5 hardware accelerator failed" );
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_NET_C)
- if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
- if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" );
- if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
- if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) )
- mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" );
- if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) )
- mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
- if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
- if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
- mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
- if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "NET - Input invalid" );
+ case -(MBEDTLS_ERR_NET_SOCKET_FAILED):
+ return( "NET - Failed to open a socket" );
+ case -(MBEDTLS_ERR_NET_CONNECT_FAILED):
+ return( "NET - The connection to the given server / port failed" );
+ case -(MBEDTLS_ERR_NET_BIND_FAILED):
+ return( "NET - Binding of the socket failed" );
+ case -(MBEDTLS_ERR_NET_LISTEN_FAILED):
+ return( "NET - Could not listen on the socket" );
+ case -(MBEDTLS_ERR_NET_ACCEPT_FAILED):
+ return( "NET - Could not accept the incoming connection" );
+ case -(MBEDTLS_ERR_NET_RECV_FAILED):
+ return( "NET - Reading information from the socket failed" );
+ case -(MBEDTLS_ERR_NET_SEND_FAILED):
+ return( "NET - Sending information through the socket failed" );
+ case -(MBEDTLS_ERR_NET_CONN_RESET):
+ return( "NET - Connection was reset by peer" );
+ case -(MBEDTLS_ERR_NET_UNKNOWN_HOST):
+ return( "NET - Failed to get an IP address for the given hostname" );
+ case -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL):
+ return( "NET - Buffer is too small to hold the data" );
+ case -(MBEDTLS_ERR_NET_INVALID_CONTEXT):
+ return( "NET - The context is invalid, eg because it was free()ed" );
+ case -(MBEDTLS_ERR_NET_POLL_FAILED):
+ return( "NET - Polling the net context failed" );
+ case -(MBEDTLS_ERR_NET_BAD_INPUT_DATA):
+ return( "NET - Input invalid" );
#endif /* MBEDTLS_NET_C */
#if defined(MBEDTLS_OID_C)
- if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) )
- mbedtls_snprintf( buf, buflen, "OID - OID is not found" );
- if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" );
+ case -(MBEDTLS_ERR_OID_NOT_FOUND):
+ return( "OID - OID is not found" );
+ case -(MBEDTLS_ERR_OID_BUF_TOO_SMALL):
+ return( "OID - output buffer is too small" );
#endif /* MBEDTLS_OID_C */
#if defined(MBEDTLS_PADLOCK_C)
- if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) )
- mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
+ case -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED):
+ return( "PADLOCK - Input data should be aligned" );
#endif /* MBEDTLS_PADLOCK_C */
#if defined(MBEDTLS_PLATFORM_C)
- if( use_ret == -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "PLATFORM - Hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED) )
- mbedtls_snprintf( buf, buflen, "PLATFORM - The requested feature is not supported by the platform" );
+ case -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED):
+ return( "PLATFORM - Hardware accelerator failed" );
+ case -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED):
+ return( "PLATFORM - The requested feature is not supported by the platform" );
#endif /* MBEDTLS_PLATFORM_C */
#if defined(MBEDTLS_POLY1305_C)
- if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" );
- if( use_ret == -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "POLY1305 - Feature not available. For example, s part of the API is not implemented" );
- if( use_ret == -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "POLY1305 - Poly1305 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA):
+ return( "POLY1305 - Invalid input parameter(s)" );
+ case -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE):
+ return( "POLY1305 - Feature not available. For example, s part of the API is not implemented" );
+ case -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED):
+ return( "POLY1305 - Poly1305 hardware accelerator failed" );
#endif /* MBEDTLS_POLY1305_C */
#if defined(MBEDTLS_RIPEMD160_C)
- if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED):
+ return( "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
#endif /* MBEDTLS_RIPEMD160_C */
#if defined(MBEDTLS_SHA1_C)
- if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 input data was malformed" );
+ case -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED):
+ return( "SHA1 - SHA-1 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA):
+ return( "SHA1 - SHA-1 input data was malformed" );
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
- if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 input data was malformed" );
+ case -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED):
+ return( "SHA256 - SHA-256 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA):
+ return( "SHA256 - SHA-256 input data was malformed" );
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
- if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 input data was malformed" );
+ case -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED):
+ return( "SHA512 - SHA-512 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA):
+ return( "SHA512 - SHA-512 input data was malformed" );
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_THREADING_C)
- if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) )
- mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" );
+ case -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE):
+ return( "THREADING - The selected feature is not available" );
+ case -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA):
+ return( "THREADING - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_THREADING_MUTEX_ERROR):
+ return( "THREADING - Locking / unlocking / free failed with error code" );
#endif /* MBEDTLS_THREADING_C */
#if defined(MBEDTLS_XTEA_C)
- if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
- if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" );
+ case -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH):
+ return( "XTEA - The data input has an invalid length" );
+ case -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED):
+ return( "XTEA - XTEA hardware accelerator failed" );
#endif /* MBEDTLS_XTEA_C */
- // END generated code
+ /* End Auto-Generated Code. */
+
+ default:
+ break;
+ }
+
+ return( NULL );
+}
+
+void mbedtls_strerror( int ret, char *buf, size_t buflen )
+{
+ size_t len;
+ int use_ret;
+ const char * high_level_error_description = NULL;
+ const char * low_level_error_description = NULL;
+
+ if( buflen == 0 )
+ return;
+
+ memset( buf, 0x00, buflen );
+
+ if( ret < 0 )
+ ret = -ret;
+
+ if( ret & 0xFF80 )
+ {
+ use_ret = ret & 0xFF80;
+
+ // Translate high level error code.
+ high_level_error_description = mbedtls_high_level_strerr( ret );
+
+ if( high_level_error_description == NULL )
+ mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret );
+ else
+ mbedtls_snprintf( buf, buflen, "%s", high_level_error_description );
+
+#if defined(MBEDTLS_SSL_TLS_C)
+ // Early return in case of a fatal error - do not try to translate low
+ // level code.
+ if(use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE))
+ return;
+#endif /* MBEDTLS_SSL_TLS_C */
+ }
- if( strlen( buf ) != 0 )
+ use_ret = ret & ~0xFF80;
+
+ if( use_ret == 0 )
return;
- mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
+ // If high level code is present, make a concatenation between both
+ // error strings.
+ //
+ len = strlen( buf );
+
+ if( len > 0 )
+ {
+ if( buflen - len < 5 )
+ return;
+
+ mbedtls_snprintf( buf + len, buflen - len, " : " );
+
+ buf += len + 3;
+ buflen -= len + 3;
+ }
+
+ // Translate low level error code.
+ low_level_error_description = mbedtls_low_level_strerr( ret );
+
+ if( low_level_error_description == NULL )
+ mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret );
+ else
+ mbedtls_snprintf( buf, buflen, "%s", low_level_error_description );
}
#else /* MBEDTLS_ERROR_C */
@@ -941,4 +973,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
#endif /* MBEDTLS_ERROR_C */
+#if defined(MBEDTLS_TEST_HOOKS)
+void (*mbedtls_test_hook_error_add)( int, int, const char *, int );
+#endif
+
#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
diff --git a/thirdparty/mbedtls/library/gcm.c b/thirdparty/mbedtls/library/gcm.c
index 441ed69a82..43a5e1bec6 100644
--- a/thirdparty/mbedtls/library/gcm.c
+++ b/thirdparty/mbedtls/library/gcm.c
@@ -2,13 +2,7 @@
* NIST SP800-38D compliant GCM implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -54,16 +27,13 @@
* [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -89,43 +59,6 @@
MBEDTLS_INTERNAL_VALIDATE( cond )
/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
-#ifndef PUT_UINT64_BE
-#define PUT_UINT64_BE( n, b, i ) \
-{ \
- ( b )[( i ) ] = (unsigned char) ( ( (n) >> 56 ) & 0xff ); \
- ( b )[( i ) + 1] = (unsigned char) ( ( (n) >> 48 ) & 0xff ); \
- ( b )[( i ) + 2] = (unsigned char) ( ( (n) >> 40 ) & 0xff ); \
- ( b )[( i ) + 3] = (unsigned char) ( ( (n) >> 32 ) & 0xff ); \
- ( b )[( i ) + 4] = (unsigned char) ( ( (n) >> 24 ) & 0xff ); \
- ( b )[( i ) + 5] = (unsigned char) ( ( (n) >> 16 ) & 0xff ); \
- ( b )[( i ) + 6] = (unsigned char) ( ( (n) >> 8 ) & 0xff ); \
- ( b )[( i ) + 7] = (unsigned char) ( ( (n) ) & 0xff ); \
-}
-#endif
-
-/*
* Initialize a context
*/
void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
@@ -155,12 +88,12 @@ static int gcm_gen_table( mbedtls_gcm_context *ctx )
return( ret );
/* pack h as two 64-bits ints, big-endian */
- GET_UINT32_BE( hi, h, 0 );
- GET_UINT32_BE( lo, h, 4 );
+ hi = MBEDTLS_GET_UINT32_BE( h, 0 );
+ lo = MBEDTLS_GET_UINT32_BE( h, 4 );
vh = (uint64_t) hi << 32 | lo;
- GET_UINT32_BE( hi, h, 8 );
- GET_UINT32_BE( lo, h, 12 );
+ hi = MBEDTLS_GET_UINT32_BE( h, 8 );
+ lo = MBEDTLS_GET_UINT32_BE( h, 12 );
vl = (uint64_t) hi << 32 | lo;
/* 8 = 1000 corresponds to 1 in GF(2^128) */
@@ -207,14 +140,15 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
const unsigned char *key,
unsigned int keybits )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
GCM_VALIDATE_RET( ctx != NULL );
GCM_VALIDATE_RET( key != NULL );
GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
- cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
+ cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
+ MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -266,10 +200,10 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
unsigned char h[16];
- PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
- PUT_UINT32_BE( ctx->HH[8], h, 4 );
- PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
- PUT_UINT32_BE( ctx->HL[8], h, 12 );
+ MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
+ MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
+ MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
+ MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
mbedtls_aesni_gcm_mult( output, x, h );
return;
@@ -284,7 +218,7 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
for( i = 15; i >= 0; i-- )
{
lo = x[i] & 0xf;
- hi = x[i] >> 4;
+ hi = ( x[i] >> 4 ) & 0xf;
if( i != 15 )
{
@@ -305,10 +239,10 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
zl ^= ctx->HL[hi];
}
- PUT_UINT32_BE( zh >> 32, output, 0 );
- PUT_UINT32_BE( zh, output, 4 );
- PUT_UINT32_BE( zl >> 32, output, 8 );
- PUT_UINT32_BE( zl, output, 12 );
+ MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
+ MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
}
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
@@ -318,7 +252,7 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
const unsigned char *add,
size_t add_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char work_buf[16];
size_t i;
const unsigned char *p;
@@ -354,7 +288,7 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
{
memset( work_buf, 0x00, 16 );
iv_bits = (uint64_t)iv_len * 8;
- PUT_UINT64_BE( iv_bits, work_buf, 8 );
+ MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
p = iv;
while( iv_len > 0 )
@@ -376,8 +310,8 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
gcm_mult( ctx, ctx->y, ctx->y );
}
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
- &olen ) ) != 0 )
+ if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
+ ctx->base_ectr, &olen ) ) != 0 )
{
return( ret );
}
@@ -405,7 +339,7 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char ectr[16];
size_t i;
const unsigned char *p;
@@ -487,10 +421,10 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
{
memset( work_buf, 0x00, 16 );
- PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
- PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
- PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
- PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
+ MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
+ MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
+ MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
+ MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
for( i = 0; i < 16; i++ )
ctx->buf[i] ^= work_buf[i];
@@ -516,7 +450,7 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
size_t tag_len,
unsigned char *tag )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
GCM_VALIDATE_RET( ctx != NULL );
GCM_VALIDATE_RET( iv != NULL );
@@ -548,7 +482,7 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
size_t i;
int diff;
@@ -598,10 +532,10 @@ void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
*/
#define MAX_TESTS 6
-static const int key_index[MAX_TESTS] =
+static const int key_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
-static const unsigned char key[MAX_TESTS][32] =
+static const unsigned char key_test_data[MAX_TESTS][32] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -613,13 +547,13 @@ static const unsigned char key[MAX_TESTS][32] =
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
};
-static const size_t iv_len[MAX_TESTS] =
+static const size_t iv_len_test_data[MAX_TESTS] =
{ 12, 12, 12, 12, 8, 60 };
-static const int iv_index[MAX_TESTS] =
+static const int iv_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 2 };
-static const unsigned char iv[MAX_TESTS][64] =
+static const unsigned char iv_test_data[MAX_TESTS][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
@@ -635,13 +569,13 @@ static const unsigned char iv[MAX_TESTS][64] =
0xa6, 0x37, 0xb3, 0x9b },
};
-static const size_t add_len[MAX_TESTS] =
+static const size_t add_len_test_data[MAX_TESTS] =
{ 0, 0, 0, 20, 20, 20 };
-static const int add_index[MAX_TESTS] =
+static const int add_index_test_data[MAX_TESTS] =
{ 0, 0, 0, 1, 1, 1 };
-static const unsigned char additional[MAX_TESTS][64] =
+static const unsigned char additional_test_data[MAX_TESTS][64] =
{
{ 0x00 },
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
@@ -649,13 +583,13 @@ static const unsigned char additional[MAX_TESTS][64] =
0xab, 0xad, 0xda, 0xd2 },
};
-static const size_t pt_len[MAX_TESTS] =
+static const size_t pt_len_test_data[MAX_TESTS] =
{ 0, 16, 64, 60, 60, 60 };
-static const int pt_index[MAX_TESTS] =
+static const int pt_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
-static const unsigned char pt[MAX_TESTS][64] =
+static const unsigned char pt_test_data[MAX_TESTS][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -669,7 +603,7 @@ static const unsigned char pt[MAX_TESTS][64] =
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
};
-static const unsigned char ct[MAX_TESTS * 3][64] =
+static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
{
{ 0x00 },
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
@@ -778,7 +712,7 @@ static const unsigned char ct[MAX_TESTS * 3][64] =
0x44, 0xae, 0x7e, 0x3f },
};
-static const unsigned char tag[MAX_TESTS * 3][16] =
+static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
{
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
@@ -838,7 +772,8 @@ int mbedtls_gcm_self_test( int verbose )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "enc" );
- ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
key_len );
/*
* AES-192 is an optional feature that may be unavailable when
@@ -856,15 +791,28 @@ int mbedtls_gcm_self_test( int verbose )
}
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
- pt_len[i],
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i],
- pt[pt_index[i]], buf, 16, tag_buf );
+ pt_len_test_data[i],
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i],
+ pt_test_data[pt_index_test_data[i]],
+ buf, 16, tag_buf );
+#if defined(MBEDTLS_GCM_ALT)
+ /* Allow alternative implementations to only support 12-byte nonces. */
+ if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
+ iv_len_test_data[i] != 12 )
+ {
+ mbedtls_printf( "skipped\n" );
+ break;
+ }
+#endif /* defined(MBEDTLS_GCM_ALT) */
if( ret != 0 )
goto exit;
- if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+ if ( memcmp( buf, ct_test_data[j * 6 + i],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
@@ -881,22 +829,26 @@ int mbedtls_gcm_self_test( int verbose )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "dec" );
- ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
- pt_len[i],
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i],
- ct[j * 6 + i], buf, 16, tag_buf );
+ pt_len_test_data[i],
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i],
+ ct_test_data[j * 6 + i], buf, 16, tag_buf );
if( ret != 0 )
goto exit;
- if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+ if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
@@ -913,32 +865,40 @@ int mbedtls_gcm_self_test( int verbose )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "enc" );
- ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i] );
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i] );
if( ret != 0 )
goto exit;
- if( pt_len[i] > 32 )
+ if( pt_len_test_data[i] > 32 )
{
- size_t rest_len = pt_len[i] - 32;
- ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
+ size_t rest_len = pt_len_test_data[i] - 32;
+ ret = mbedtls_gcm_update( &ctx, 32,
+ pt_test_data[pt_index_test_data[i]],
+ buf );
if( ret != 0 )
goto exit;
- ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
- buf + 32 );
+ ret = mbedtls_gcm_update( &ctx, rest_len,
+ pt_test_data[pt_index_test_data[i]] + 32,
+ buf + 32 );
if( ret != 0 )
goto exit;
}
else
{
- ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
+ ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
+ pt_test_data[pt_index_test_data[i]],
+ buf );
if( ret != 0 )
goto exit;
}
@@ -947,8 +907,9 @@ int mbedtls_gcm_self_test( int verbose )
if( ret != 0 )
goto exit;
- if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+ if( memcmp( buf, ct_test_data[j * 6 + i],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
@@ -965,32 +926,38 @@ int mbedtls_gcm_self_test( int verbose )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "dec" );
- ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i] );
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i] );
if( ret != 0 )
goto exit;
- if( pt_len[i] > 32 )
+ if( pt_len_test_data[i] > 32 )
{
- size_t rest_len = pt_len[i] - 32;
- ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
+ size_t rest_len = pt_len_test_data[i] - 32;
+ ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
+ buf );
if( ret != 0 )
goto exit;
- ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
+ ret = mbedtls_gcm_update( &ctx, rest_len,
+ ct_test_data[j * 6 + i] + 32,
buf + 32 );
if( ret != 0 )
goto exit;
}
else
{
- ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
+ ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
+ ct_test_data[j * 6 + i],
buf );
if( ret != 0 )
goto exit;
@@ -1000,8 +967,9 @@ int mbedtls_gcm_self_test( int verbose )
if( ret != 0 )
goto exit;
- if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+ if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
diff --git a/thirdparty/mbedtls/library/havege.c b/thirdparty/mbedtls/library/havege.c
index 5e91f40d84..2a360a150c 100644
--- a/thirdparty/mbedtls/library/havege.c
+++ b/thirdparty/mbedtls/library/havege.c
@@ -2,13 +2,7 @@
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The HAVEGE RNG was designed by Andre Seznec in 2002.
@@ -51,11 +24,7 @@
* Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_HAVEGE_C)
@@ -63,19 +32,9 @@
#include "mbedtls/timing.h"
#include "mbedtls/platform_util.h"
-#include <limits.h>
+#include <stdint.h>
#include <string.h>
-/* If int isn't capable of storing 2^32 distinct values, the code of this
- * module may cause a processor trap or a miscalculation. If int is more
- * than 32 bits, the code may not calculate the intended values. */
-#if INT_MIN + 1 != -0x7fffffff
-#error "The HAVEGE module requires int to be exactly 32 bits, with INT_MIN = -2^31."
-#endif
-#if UINT_MAX != 0xffffffff
-#error "The HAVEGE module requires unsigned to be exactly 32 bits."
-#endif
-
/* ------------------------------------------------------------------------
* On average, one iteration accesses two 8-word blocks in the havege WALK
* table, and generates 16 words in the RES array.
@@ -90,7 +49,7 @@
* ------------------------------------------------------------------------
*/
-#define SWAP(X,Y) { unsigned *T = (X); (X) = (Y); (Y) = T; }
+#define SWAP(X,Y) { uint32_t *T = (X); (X) = (Y); (Y) = T; }
#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
@@ -113,7 +72,7 @@
PTX = (PT1 >> 18) & 7; \
PT1 &= 0x1FFF; \
PT2 &= 0x1FFF; \
- CLK = (unsigned) mbedtls_timing_hardclock(); \
+ CLK = (uint32_t) mbedtls_timing_hardclock(); \
\
i = 0; \
A = &WALK[PT1 ]; RES[i++] ^= *A; \
@@ -136,7 +95,7 @@
\
IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
*A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
- *B = IN; CLK = (unsigned) mbedtls_timing_hardclock(); \
+ *B = IN; CLK = (uint32_t) mbedtls_timing_hardclock(); \
*C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
*D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
\
@@ -187,20 +146,20 @@
PT1 ^= (PT2 ^ 0x10) & 0x10; \
\
for( n++, i = 0; i < 16; i++ ) \
- POOL[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
+ hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
/*
* Entropy gathering function
*/
static void havege_fill( mbedtls_havege_state *hs )
{
- unsigned i, n = 0;
- unsigned U1, U2, *A, *B, *C, *D;
- unsigned PT1, PT2, *WALK, *POOL, RES[16];
- unsigned PTX, PTY, CLK, PTEST, IN;
+ size_t n = 0;
+ size_t i;
+ uint32_t U1, U2, *A, *B, *C, *D;
+ uint32_t PT1, PT2, *WALK, RES[16];
+ uint32_t PTX, PTY, CLK, PTEST, IN;
- WALK = (unsigned *) hs->WALK;
- POOL = (unsigned *) hs->pool;
+ WALK = hs->WALK;
PT1 = hs->PT1;
PT2 = hs->PT2;
@@ -249,7 +208,7 @@ void mbedtls_havege_free( mbedtls_havege_state *hs )
*/
int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
{
- int val;
+ uint32_t val;
size_t use_len;
mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng;
unsigned char *p = buf;
@@ -257,8 +216,8 @@ int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
while( len > 0 )
{
use_len = len;
- if( use_len > sizeof(int) )
- use_len = sizeof(int);
+ if( use_len > sizeof( val ) )
+ use_len = sizeof( val );
if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE )
havege_fill( hs );
diff --git a/thirdparty/mbedtls/library/hkdf.c b/thirdparty/mbedtls/library/hkdf.c
index 4a8bdfbe18..5013729d2a 100644
--- a/thirdparty/mbedtls/library/hkdf.c
+++ b/thirdparty/mbedtls/library/hkdf.c
@@ -2,13 +2,7 @@
* HKDF implementation -- RFC 5869
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,46 +15,22 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_HKDF_C)
#include <string.h>
#include "mbedtls/hkdf.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char prk[MBEDTLS_MD_MAX_SIZE];
ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
@@ -139,7 +109,7 @@ int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
n = okm_len / hash_len;
- if( (okm_len % hash_len) != 0 )
+ if( okm_len % hash_len != 0 )
{
n++;
}
@@ -155,11 +125,13 @@ int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
mbedtls_md_init( &ctx );
- if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 )
+ if( ( ret = mbedtls_md_setup( &ctx, md, 1 ) ) != 0 )
{
goto exit;
}
+ memset( t, 0, hash_len );
+
/*
* Compute T = T(1) | T(2) | T(3) | ... | T(N)
* Where T(N) is defined in RFC 5869 Section 2.3
diff --git a/thirdparty/mbedtls/library/hmac_drbg.c b/thirdparty/mbedtls/library/hmac_drbg.c
index b45d61616f..de9706885c 100644
--- a/thirdparty/mbedtls/library/hmac_drbg.c
+++ b/thirdparty/mbedtls/library/hmac_drbg.c
@@ -2,13 +2,7 @@
* HMAC_DRBG implementation (NIST SP 800-90)
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -50,16 +23,13 @@
* References below are based on rev. 1 (January 2012).
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -97,7 +67,7 @@ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
unsigned char sep[1];
unsigned char K[MBEDTLS_MD_MAX_SIZE];
- int ret;
+ int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
{
@@ -150,7 +120,7 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
const mbedtls_md_info_t * md_info,
const unsigned char *data, size_t data_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
return( ret );
@@ -186,7 +156,7 @@ static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
{
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
{
size_t total_entropy_len;
@@ -278,7 +248,7 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
const unsigned char *custom,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t md_size;
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
@@ -359,7 +329,7 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t out_len,
const unsigned char *additional, size_t add_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
size_t left = out_len;
@@ -428,7 +398,7 @@ exit:
*/
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
#if defined(MBEDTLS_THREADING_C)
@@ -468,7 +438,7 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
#if defined(MBEDTLS_FS_IO)
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
FILE *f;
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
diff --git a/thirdparty/mbedtls/library/md.c b/thirdparty/mbedtls/library/md.c
index 867b91462d..a10a835634 100644
--- a/thirdparty/mbedtls/library/md.c
+++ b/thirdparty/mbedtls/library/md.c
@@ -1,18 +1,12 @@
/**
- * \file mbedtls_md.c
+ * \file md.c
*
* \brief Generic message digest wrapper for mbed TLS
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,40 +19,24 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MD_C)
#include "mbedtls/md.h"
#include "mbedtls/md_internal.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+
+#include "mbedtls/md2.h"
+#include "mbedtls/md4.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/ripemd160.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
@@ -74,6 +52,85 @@
#include <stdio.h>
#endif
+#if defined(MBEDTLS_MD2_C)
+const mbedtls_md_info_t mbedtls_md2_info = {
+ "MD2",
+ MBEDTLS_MD_MD2,
+ 16,
+ 16,
+};
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+const mbedtls_md_info_t mbedtls_md4_info = {
+ "MD4",
+ MBEDTLS_MD_MD4,
+ 16,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+const mbedtls_md_info_t mbedtls_md5_info = {
+ "MD5",
+ MBEDTLS_MD_MD5,
+ 16,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+const mbedtls_md_info_t mbedtls_ripemd160_info = {
+ "RIPEMD160",
+ MBEDTLS_MD_RIPEMD160,
+ 20,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+const mbedtls_md_info_t mbedtls_sha1_info = {
+ "SHA1",
+ MBEDTLS_MD_SHA1,
+ 20,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+const mbedtls_md_info_t mbedtls_sha224_info = {
+ "SHA224",
+ MBEDTLS_MD_SHA224,
+ 28,
+ 64,
+};
+
+const mbedtls_md_info_t mbedtls_sha256_info = {
+ "SHA256",
+ MBEDTLS_MD_SHA256,
+ 32,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+const mbedtls_md_info_t mbedtls_sha384_info = {
+ "SHA384",
+ MBEDTLS_MD_SHA384,
+ 48,
+ 128,
+};
+#endif
+
+const mbedtls_md_info_t mbedtls_sha512_info = {
+ "SHA512",
+ MBEDTLS_MD_SHA512,
+ 64,
+ 128,
+};
+#endif
+
/*
* Reminder: update profiles in x509_crt.c when adding a new hash!
*/
@@ -81,8 +138,10 @@ static const int supported_digests[] = {
#if defined(MBEDTLS_SHA512_C)
MBEDTLS_MD_SHA512,
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
MBEDTLS_MD_SHA384,
#endif
+#endif
#if defined(MBEDTLS_SHA256_C)
MBEDTLS_MD_SHA256,
@@ -150,8 +209,10 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
#endif
#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
if( !strcmp( "SHA384", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
+#endif
if( !strcmp( "SHA512", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
#endif
@@ -189,8 +250,10 @@ const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
return( &mbedtls_sha256_info );
#endif
#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
case MBEDTLS_MD_SHA384:
return( &mbedtls_sha384_info );
+#endif
case MBEDTLS_MD_SHA512:
return( &mbedtls_sha512_info );
#endif
@@ -210,7 +273,54 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx )
return;
if( ctx->md_ctx != NULL )
- ctx->md_info->ctx_free_func( ctx->md_ctx );
+ {
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ mbedtls_md2_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ mbedtls_md4_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ mbedtls_md5_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ mbedtls_ripemd160_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ mbedtls_sha1_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ mbedtls_sha256_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ mbedtls_sha512_free( ctx->md_ctx );
+ break;
+#endif
+ default:
+ /* Shouldn't happen */
+ break;
+ }
+ mbedtls_free( ctx->md_ctx );
+ }
if( ctx->hmac_ctx != NULL )
{
@@ -232,7 +342,50 @@ int mbedtls_md_clone( mbedtls_md_context_t *dst,
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
}
- dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
+ switch( src->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ mbedtls_md2_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ mbedtls_md4_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
return( 0 );
}
@@ -244,35 +397,127 @@ int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_
}
#endif
+#define ALLOC( type ) \
+ do { \
+ ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
+ if( ctx->md_ctx == NULL ) \
+ return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \
+ mbedtls_##type##_init( ctx->md_ctx ); \
+ } \
+ while( 0 )
+
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
{
if( md_info == NULL || ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
- return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+ ctx->md_info = md_info;
+ ctx->md_ctx = NULL;
+ ctx->hmac_ctx = NULL;
+
+ switch( md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ ALLOC( md2 );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ ALLOC( md4 );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ ALLOC( md5 );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ ALLOC( ripemd160 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ ALLOC( sha1 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ ALLOC( sha256 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ ALLOC( sha512 );
+ break;
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
if( hmac != 0 )
{
ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
if( ctx->hmac_ctx == NULL )
{
- md_info->ctx_free_func( ctx->md_ctx );
+ mbedtls_md_free( ctx );
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
}
}
- ctx->md_info = md_info;
-
return( 0 );
}
+#undef ALLOC
int mbedtls_md_starts( mbedtls_md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->starts_func( ctx->md_ctx ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) );
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@@ -280,7 +525,43 @@ int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, si
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@@ -288,7 +569,43 @@ int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
@@ -297,13 +614,51 @@ int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, si
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( md_info->digest_func( input, ilen, output ) );
+ switch( md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
#if defined(MBEDTLS_FS_IO)
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
FILE *f;
size_t n;
mbedtls_md_context_t ctx;
@@ -320,17 +675,17 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigne
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
goto cleanup;
- if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
goto cleanup;
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
- if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
+ if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
goto cleanup;
if( ferror( f ) != 0 )
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
else
- ret = md_info->finish_func( ctx.md_ctx, output );
+ ret = mbedtls_md_finish( &ctx, output );
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -343,7 +698,7 @@ cleanup:
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char sum[MBEDTLS_MD_MAX_SIZE];
unsigned char *ipad, *opad;
size_t i;
@@ -353,11 +708,11 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
if( keylen > (size_t) ctx->md_info->block_size )
{
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
goto cleanup;
keylen = ctx->md_info->size;
@@ -376,10 +731,10 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
opad[i] = (unsigned char)( opad[i] ^ key[i] );
}
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
- ctx->md_info->block_size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, ipad,
+ ctx->md_info->block_size ) ) != 0 )
goto cleanup;
cleanup:
@@ -393,12 +748,12 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+ return( mbedtls_md_update( ctx, input, ilen ) );
}
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
unsigned char *opad;
@@ -407,22 +762,22 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
- if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
- ctx->md_info->block_size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, opad,
+ ctx->md_info->block_size ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
- ctx->md_info->size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, tmp,
+ ctx->md_info->size ) ) != 0 )
return( ret );
- return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+ return( mbedtls_md_finish( ctx, output ) );
}
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *ipad;
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
@@ -430,10 +785,9 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
ipad = (unsigned char *) ctx->hmac_ctx;
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
return( ret );
- return( ctx->md_info->update_func( ctx->md_ctx, ipad,
- ctx->md_info->block_size ) );
+ return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
}
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
@@ -442,7 +796,7 @@ int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
unsigned char *output )
{
mbedtls_md_context_t ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
@@ -470,7 +824,43 @@ int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->process_func( ctx->md_ctx, data ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_internal_md2_process( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_internal_md4_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
diff --git a/thirdparty/mbedtls/library/md2.c b/thirdparty/mbedtls/library/md2.c
index 58bd6d8f6b..7264e30313 100644
--- a/thirdparty/mbedtls/library/md2.c
+++ b/thirdparty/mbedtls/library/md2.c
@@ -2,13 +2,7 @@
* RFC 1115/1319 compliant MD2 implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The MD2 algorithm was designed by Ron Rivest in 1989.
@@ -50,16 +23,13 @@
* http://www.ietf.org/rfc/rfc1319.txt
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MD2_C)
#include "mbedtls/md2.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -198,7 +168,7 @@ int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
while( ilen > 0 )
@@ -240,7 +210,7 @@ void mbedtls_md2_update( mbedtls_md2_context *ctx,
int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
unsigned char x;
@@ -278,7 +248,7 @@ int mbedtls_md2_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md2_context ctx;
mbedtls_md2_init( &ctx );
diff --git a/thirdparty/mbedtls/library/md4.c b/thirdparty/mbedtls/library/md4.c
index 9a825327f4..eaa679a0a6 100644
--- a/thirdparty/mbedtls/library/md4.c
+++ b/thirdparty/mbedtls/library/md4.c
@@ -2,13 +2,7 @@
* RFC 1186/1320 compliant MD4 implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The MD4 algorithm was designed by Ron Rivest in 1990.
@@ -50,16 +23,13 @@
* http://www.ietf.org/rfc/rfc1320.txt
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MD4_C)
#include "mbedtls/md4.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -74,29 +44,6 @@
#if !defined(MBEDTLS_MD4_ALT)
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
void mbedtls_md4_init( mbedtls_md4_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md4_context ) );
@@ -148,22 +95,22 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
uint32_t X[16], A, B, C, D;
} local;
- GET_UINT32_LE( local.X[ 0], data, 0 );
- GET_UINT32_LE( local.X[ 1], data, 4 );
- GET_UINT32_LE( local.X[ 2], data, 8 );
- GET_UINT32_LE( local.X[ 3], data, 12 );
- GET_UINT32_LE( local.X[ 4], data, 16 );
- GET_UINT32_LE( local.X[ 5], data, 20 );
- GET_UINT32_LE( local.X[ 6], data, 24 );
- GET_UINT32_LE( local.X[ 7], data, 28 );
- GET_UINT32_LE( local.X[ 8], data, 32 );
- GET_UINT32_LE( local.X[ 9], data, 36 );
- GET_UINT32_LE( local.X[10], data, 40 );
- GET_UINT32_LE( local.X[11], data, 44 );
- GET_UINT32_LE( local.X[12], data, 48 );
- GET_UINT32_LE( local.X[13], data, 52 );
- GET_UINT32_LE( local.X[14], data, 56 );
- GET_UINT32_LE( local.X[15], data, 60 );
+ local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
+ local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
+ local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
+ local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+ local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+ local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+ local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+ local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+ local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+ local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+ local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+ local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+ local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+ local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+ local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+ local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
@@ -284,7 +231,7 @@ int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -354,7 +301,7 @@ static const unsigned char md4_padding[64] =
int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
@@ -363,8 +310,8 @@ int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, msglen, 0 );
- PUT_UINT32_LE( high, msglen, 4 );
+ MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
+ MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
@@ -377,10 +324,10 @@ int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
return( ret );
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
return( 0 );
}
@@ -402,7 +349,7 @@ int mbedtls_md4_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md4_context ctx;
mbedtls_md4_init( &ctx );
diff --git a/thirdparty/mbedtls/library/md5.c b/thirdparty/mbedtls/library/md5.c
index a2e1ca77ad..4b53fcf367 100644
--- a/thirdparty/mbedtls/library/md5.c
+++ b/thirdparty/mbedtls/library/md5.c
@@ -2,13 +2,7 @@
* RFC 1321 compliant MD5 implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The MD5 algorithm was designed by Ron Rivest in 1991.
@@ -49,16 +22,13 @@
* http://www.ietf.org/rfc/rfc1321.txt
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MD5_C)
#include "mbedtls/md5.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -73,29 +43,6 @@
#if !defined(MBEDTLS_MD5_ALT)
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
void mbedtls_md5_init( mbedtls_md5_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md5_context ) );
@@ -147,22 +94,22 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
uint32_t X[16], A, B, C, D;
} local;
- GET_UINT32_LE( local.X[ 0], data, 0 );
- GET_UINT32_LE( local.X[ 1], data, 4 );
- GET_UINT32_LE( local.X[ 2], data, 8 );
- GET_UINT32_LE( local.X[ 3], data, 12 );
- GET_UINT32_LE( local.X[ 4], data, 16 );
- GET_UINT32_LE( local.X[ 5], data, 20 );
- GET_UINT32_LE( local.X[ 6], data, 24 );
- GET_UINT32_LE( local.X[ 7], data, 28 );
- GET_UINT32_LE( local.X[ 8], data, 32 );
- GET_UINT32_LE( local.X[ 9], data, 36 );
- GET_UINT32_LE( local.X[10], data, 40 );
- GET_UINT32_LE( local.X[11], data, 44 );
- GET_UINT32_LE( local.X[12], data, 48 );
- GET_UINT32_LE( local.X[13], data, 52 );
- GET_UINT32_LE( local.X[14], data, 56 );
- GET_UINT32_LE( local.X[15], data, 60 );
+ local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
+ local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
+ local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
+ local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+ local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+ local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+ local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+ local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+ local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+ local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+ local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+ local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+ local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+ local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+ local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+ local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
#define S(x,n) \
( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) )
@@ -290,7 +237,7 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -349,7 +296,7 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx,
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t used;
uint32_t high, low;
@@ -383,8 +330,8 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, ctx->buffer, 56 );
- PUT_UINT32_LE( high, ctx->buffer, 60 );
+ MBEDTLS_PUT_UINT32_LE( low, ctx->buffer, 56 );
+ MBEDTLS_PUT_UINT32_LE( high, ctx->buffer, 60 );
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@@ -392,10 +339,10 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
/*
* Output final state
*/
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
return( 0 );
}
@@ -417,7 +364,7 @@ int mbedtls_md5_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md5_context ctx;
mbedtls_md5_init( &ctx );
diff --git a/thirdparty/mbedtls/library/md_wrap.c b/thirdparty/mbedtls/library/md_wrap.c
deleted file mode 100644
index 7459db2faf..0000000000
--- a/thirdparty/mbedtls/library/md_wrap.c
+++ /dev/null
@@ -1,611 +0,0 @@
-/**
- * \file md_wrap.c
- *
- * \brief Generic message digest wrapper for mbed TLS
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_MD_C)
-
-#include "mbedtls/md_internal.h"
-
-#if defined(MBEDTLS_MD2_C)
-#include "mbedtls/md2.h"
-#endif
-
-#if defined(MBEDTLS_MD4_C)
-#include "mbedtls/md4.h"
-#endif
-
-#if defined(MBEDTLS_MD5_C)
-#include "mbedtls/md5.h"
-#endif
-
-#if defined(MBEDTLS_RIPEMD160_C)
-#include "mbedtls/ripemd160.h"
-#endif
-
-#if defined(MBEDTLS_SHA1_C)
-#include "mbedtls/sha1.h"
-#endif
-
-#if defined(MBEDTLS_SHA256_C)
-#include "mbedtls/sha256.h"
-#endif
-
-#if defined(MBEDTLS_SHA512_C)
-#include "mbedtls/sha512.h"
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#endif
-
-#if defined(MBEDTLS_MD2_C)
-
-static int md2_starts_wrap( void *ctx )
-{
- return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
-}
-
-static int md2_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
-}
-
-static int md2_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
-}
-
-static void *md2_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) );
-
- if( ctx != NULL )
- mbedtls_md2_init( (mbedtls_md2_context *) ctx );
-
- return( ctx );
-}
-
-static void md2_ctx_free( void *ctx )
-{
- mbedtls_md2_free( (mbedtls_md2_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md2_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md2_clone( (mbedtls_md2_context *) dst,
- (const mbedtls_md2_context *) src );
-}
-
-static int md2_process_wrap( void *ctx, const unsigned char *data )
-{
- ((void) data);
-
- return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
-}
-
-const mbedtls_md_info_t mbedtls_md2_info = {
- MBEDTLS_MD_MD2,
- "MD2",
- 16,
- 16,
- md2_starts_wrap,
- md2_update_wrap,
- md2_finish_wrap,
- mbedtls_md2_ret,
- md2_ctx_alloc,
- md2_ctx_free,
- md2_clone_wrap,
- md2_process_wrap,
-};
-
-#endif /* MBEDTLS_MD2_C */
-
-#if defined(MBEDTLS_MD4_C)
-
-static int md4_starts_wrap( void *ctx )
-{
- return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
-}
-
-static int md4_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
-}
-
-static int md4_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
-}
-
-static void *md4_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) );
-
- if( ctx != NULL )
- mbedtls_md4_init( (mbedtls_md4_context *) ctx );
-
- return( ctx );
-}
-
-static void md4_ctx_free( void *ctx )
-{
- mbedtls_md4_free( (mbedtls_md4_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md4_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md4_clone( (mbedtls_md4_context *) dst,
- (const mbedtls_md4_context *) src );
-}
-
-static int md4_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_md4_info = {
- MBEDTLS_MD_MD4,
- "MD4",
- 16,
- 64,
- md4_starts_wrap,
- md4_update_wrap,
- md4_finish_wrap,
- mbedtls_md4_ret,
- md4_ctx_alloc,
- md4_ctx_free,
- md4_clone_wrap,
- md4_process_wrap,
-};
-
-#endif /* MBEDTLS_MD4_C */
-
-#if defined(MBEDTLS_MD5_C)
-
-static int md5_starts_wrap( void *ctx )
-{
- return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
-}
-
-static int md5_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
-}
-
-static int md5_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
-}
-
-static void *md5_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) );
-
- if( ctx != NULL )
- mbedtls_md5_init( (mbedtls_md5_context *) ctx );
-
- return( ctx );
-}
-
-static void md5_ctx_free( void *ctx )
-{
- mbedtls_md5_free( (mbedtls_md5_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md5_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md5_clone( (mbedtls_md5_context *) dst,
- (const mbedtls_md5_context *) src );
-}
-
-static int md5_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_md5_info = {
- MBEDTLS_MD_MD5,
- "MD5",
- 16,
- 64,
- md5_starts_wrap,
- md5_update_wrap,
- md5_finish_wrap,
- mbedtls_md5_ret,
- md5_ctx_alloc,
- md5_ctx_free,
- md5_clone_wrap,
- md5_process_wrap,
-};
-
-#endif /* MBEDTLS_MD5_C */
-
-#if defined(MBEDTLS_RIPEMD160_C)
-
-static int ripemd160_starts_wrap( void *ctx )
-{
- return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
-}
-
-static int ripemd160_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
- input, ilen ) );
-}
-
-static int ripemd160_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
- output ) );
-}
-
-static void *ripemd160_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) );
-
- if( ctx != NULL )
- mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx );
-
- return( ctx );
-}
-
-static void ripemd160_ctx_free( void *ctx )
-{
- mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void ripemd160_clone_wrap( void *dst, const void *src )
-{
- mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst,
- (const mbedtls_ripemd160_context *) src );
-}
-
-static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_ripemd160_process(
- (mbedtls_ripemd160_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_ripemd160_info = {
- MBEDTLS_MD_RIPEMD160,
- "RIPEMD160",
- 20,
- 64,
- ripemd160_starts_wrap,
- ripemd160_update_wrap,
- ripemd160_finish_wrap,
- mbedtls_ripemd160_ret,
- ripemd160_ctx_alloc,
- ripemd160_ctx_free,
- ripemd160_clone_wrap,
- ripemd160_process_wrap,
-};
-
-#endif /* MBEDTLS_RIPEMD160_C */
-
-#if defined(MBEDTLS_SHA1_C)
-
-static int sha1_starts_wrap( void *ctx )
-{
- return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
-}
-
-static int sha1_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
- input, ilen ) );
-}
-
-static int sha1_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
-}
-
-static void *sha1_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) );
-
- if( ctx != NULL )
- mbedtls_sha1_init( (mbedtls_sha1_context *) ctx );
-
- return( ctx );
-}
-
-static void sha1_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha1_clone( (mbedtls_sha1_context *) dst,
- (const mbedtls_sha1_context *) src );
-}
-
-static void sha1_ctx_free( void *ctx )
-{
- mbedtls_sha1_free( (mbedtls_sha1_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static int sha1_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha1_info = {
- MBEDTLS_MD_SHA1,
- "SHA1",
- 20,
- 64,
- sha1_starts_wrap,
- sha1_update_wrap,
- sha1_finish_wrap,
- mbedtls_sha1_ret,
- sha1_ctx_alloc,
- sha1_ctx_free,
- sha1_clone_wrap,
- sha1_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA1_C */
-
-/*
- * Wrappers for generic message digests
- */
-#if defined(MBEDTLS_SHA256_C)
-
-static int sha224_starts_wrap( void *ctx )
-{
- return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
-}
-
-static int sha224_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
- input, ilen ) );
-}
-
-static int sha224_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
- output ) );
-}
-
-static int sha224_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
-}
-
-static void *sha224_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
-
- if( ctx != NULL )
- mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
-
- return( ctx );
-}
-
-static void sha224_ctx_free( void *ctx )
-{
- mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void sha224_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
- (const mbedtls_sha256_context *) src );
-}
-
-static int sha224_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha224_info = {
- MBEDTLS_MD_SHA224,
- "SHA224",
- 28,
- 64,
- sha224_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha224_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
-};
-
-static int sha256_starts_wrap( void *ctx )
-{
- return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
-}
-
-static int sha256_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha256_info = {
- MBEDTLS_MD_SHA256,
- "SHA256",
- 32,
- 64,
- sha256_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha256_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA512_C)
-
-static int sha384_starts_wrap( void *ctx )
-{
- return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
-}
-
-static int sha384_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
- input, ilen ) );
-}
-
-static int sha384_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
- output ) );
-}
-
-static int sha384_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
-}
-
-static void *sha384_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) );
-
- if( ctx != NULL )
- mbedtls_sha512_init( (mbedtls_sha512_context *) ctx );
-
- return( ctx );
-}
-
-static void sha384_ctx_free( void *ctx )
-{
- mbedtls_sha512_free( (mbedtls_sha512_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void sha384_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha512_clone( (mbedtls_sha512_context *) dst,
- (const mbedtls_sha512_context *) src );
-}
-
-static int sha384_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha384_info = {
- MBEDTLS_MD_SHA384,
- "SHA384",
- 48,
- 128,
- sha384_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha384_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
-};
-
-static int sha512_starts_wrap( void *ctx )
-{
- return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
-}
-
-static int sha512_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha512_info = {
- MBEDTLS_MD_SHA512,
- "SHA512",
- 64,
- 128,
- sha512_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha512_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA512_C */
-
-#endif /* MBEDTLS_MD_C */
diff --git a/thirdparty/mbedtls/library/memory_buffer_alloc.c b/thirdparty/mbedtls/library/memory_buffer_alloc.c
index 915ec3ae9d..0d5d27d3de 100644
--- a/thirdparty/mbedtls/library/memory_buffer_alloc.c
+++ b/thirdparty/mbedtls/library/memory_buffer_alloc.c
@@ -2,13 +2,7 @@
* Buffer-based memory allocator
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#include "mbedtls/memory_buffer_alloc.h"
diff --git a/thirdparty/mbedtls/library/mps_common.h b/thirdparty/mbedtls/library/mps_common.h
new file mode 100644
index 0000000000..d20776f159
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_common.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/**
+ * \file mps_common.h
+ *
+ * \brief Common functions and macros used by MPS
+ */
+
+#ifndef MBEDTLS_MPS_COMMON_H
+#define MBEDTLS_MPS_COMMON_H
+
+#include "mps_error.h"
+
+#include <stdio.h>
+
+/**
+ * \name SECTION: MPS Configuration
+ *
+ * \{
+ */
+
+/*! This flag controls whether the MPS-internal components
+ * (reader, writer, Layer 1-3) perform validation of the
+ * expected abstract state at the entry of API calls.
+ *
+ * Context: All MPS API functions impose assumptions/preconditions on the
+ * context on which they operate. For example, every structure has a notion of
+ * state integrity which is established by `xxx_init()` and preserved by any
+ * calls to the MPS API which satisfy their preconditions and either succeed,
+ * or fail with an error code which is explicitly documented to not corrupt
+ * structure integrity (such as WANT_READ and WANT_WRITE);
+ * apart from `xxx_init()` any function assumes state integrity as a
+ * precondition (but usually more). If any of the preconditions is violated,
+ * the function's behavior is entirely undefined.
+ * In addition to state integrity, all MPS structures have a more refined
+ * notion of abstract state that the API operates on. For example, all layers
+ * have a notion of 'abtract read state' which indicates if incoming data has
+ * been passed to the user, e.g. through mps_l2_read_start() for Layer 2
+ * or mps_l3_read() in Layer 3. After such a call, it doesn't make sense to
+ * call these reading functions again until the incoming data has been
+ * explicitly 'consumed', e.g. through mps_l2_read_consume() for Layer 2 or
+ * mps_l3_read_consume() on Layer 3. However, even if it doesn't make sense,
+ * it's a design choice whether the API should fail gracefully on such
+ * non-sensical calls or not, and that's what this option is about:
+ *
+ * This option determines whether the expected abstract state
+ * is part of the API preconditions or not: If the option is set,
+ * then the abstract state is not part of the precondition and is
+ * thus required to be validated by the implementation. If an unexpected
+ * abstract state is encountered, the implementation must fail gracefully
+ * with error #MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED.
+ * Conversely, if this option is not set, then the expected abstract state
+ * is included in the preconditions of the respective API calls, and
+ * an implementation's behaviour is undefined if the abstract state is
+ * not as expected.
+ *
+ * For example: Enabling this makes mps_l2_read_done() fail if
+ * no incoming record is currently open; disabling this would
+ * lead to undefined behavior in this case.
+ *
+ * Comment this to remove state validation.
+ */
+#define MBEDTLS_MPS_STATE_VALIDATION
+
+/*! This flag enables/disables assertions on the internal state of MPS.
+ *
+ * Assertions are sanity checks that should never trigger when MPS
+ * is used within the bounds of its API and preconditions.
+ *
+ * Enabling this increases security by limiting the scope of
+ * potential bugs, but comes at the cost of increased code size.
+ *
+ * Note: So far, there is no guiding principle as to what
+ * expected conditions merit an assertion, and which don't.
+ *
+ * Comment this to disable assertions.
+ */
+#define MBEDTLS_MPS_ENABLE_ASSERTIONS
+
+/*! This flag controls whether tracing for MPS should be enabled. */
+//#define MBEDTLS_MPS_ENABLE_TRACE
+
+#if defined(MBEDTLS_MPS_STATE_VALIDATION)
+
+#define MBEDTLS_MPS_STATE_VALIDATE_RAW( cond, string ) \
+ do \
+ { \
+ if( !(cond) ) \
+ { \
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR, string ); \
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED ); \
+ } \
+ } while( 0 )
+
+#else /* MBEDTLS_MPS_STATE_VALIDATION */
+
+#define MBEDTLS_MPS_STATE_VALIDATE_RAW( cond, string ) \
+ do \
+ { \
+ ( cond ); \
+ } while( 0 )
+
+#endif /* MBEDTLS_MPS_STATE_VALIDATION */
+
+#if defined(MBEDTLS_MPS_ENABLE_ASSERTIONS)
+
+#define MBEDTLS_MPS_ASSERT_RAW( cond, string ) \
+ do \
+ { \
+ if( !(cond) ) \
+ { \
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR, string ); \
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_INTERNAL_ERROR ); \
+ } \
+ } while( 0 )
+
+#else /* MBEDTLS_MPS_ENABLE_ASSERTIONS */
+
+#define MBEDTLS_MPS_ASSERT_RAW( cond, string ) do {} while( 0 )
+
+#endif /* MBEDTLS_MPS_ENABLE_ASSERTIONS */
+
+
+/* \} name SECTION: MPS Configuration */
+
+/**
+ * \name SECTION: Common types
+ *
+ * Various common types used throughout MPS.
+ * \{
+ */
+
+/** \brief The type of buffer sizes and offsets used in MPS structures.
+ *
+ * This is an unsigned integer type that should be large enough to
+ * hold the length of any buffer or message processed by MPS.
+ *
+ * The reason to pick a value as small as possible here is
+ * to reduce the size of MPS structures.
+ *
+ * \warning Care has to be taken when using a narrower type
+ * than ::mbedtls_mps_size_t here because of
+ * potential truncation during conversion.
+ *
+ * \warning Handshake messages in TLS may be up to 2^24 ~ 16Mb in size.
+ * If mbedtls_mps_[opt_]stored_size_t is smaller than that, the
+ * maximum handshake message is restricted accordingly.
+ *
+ * For now, we use the default type of size_t throughout, and the use of
+ * smaller types or different types for ::mbedtls_mps_size_t and
+ * ::mbedtls_mps_stored_size_t is not yet supported.
+ *
+ */
+typedef size_t mbedtls_mps_stored_size_t;
+#define MBEDTLS_MPS_STORED_SIZE_MAX ( (mbedtls_mps_stored_size_t) -1 )
+
+/** \brief The type of buffer sizes and offsets used in the MPS API
+ * and implementation.
+ *
+ * This must be at least as wide as ::mbedtls_stored_size_t but
+ * may be chosen to be strictly larger if more suitable for the
+ * target architecture.
+ *
+ * For example, in a test build for ARM Thumb, using uint_fast16_t
+ * instead of uint16_t reduced the code size from 1060 Byte to 962 Byte,
+ * so almost 10%.
+ */
+typedef size_t mbedtls_mps_size_t;
+#define MBEDTLS_MPS_SIZE_MAX ( (mbedtls_mps_size_t) -1 )
+
+#if MBEDTLS_MPS_STORED_SIZE_MAX > MBEDTLS_MPS_SIZE_MAX
+#error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t."
+#endif
+
+/* \} SECTION: Common types */
+
+
+#endif /* MBEDTLS_MPS_COMMON_H */
diff --git a/thirdparty/mbedtls/library/mps_error.h b/thirdparty/mbedtls/library/mps_error.h
new file mode 100644
index 0000000000..f78d9a05f1
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_error.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/**
+ * \file mps_error.h
+ *
+ * \brief Error codes used by MPS
+ */
+
+#ifndef MBEDTLS_MPS_ERROR_H
+#define MBEDTLS_MPS_ERROR_H
+
+
+/* TODO: The error code allocation needs to be revisited:
+ *
+ * - Should we make (some of) the MPS Reader error codes public?
+ * If so, we need to adjust MBEDTLS_MPS_READER_MAKE_ERROR() to hit
+ * a gap in the Mbed TLS public error space.
+ * If not, we have to make sure we don't forward those errors
+ * at the level of the public API -- no risk at the moment as
+ * long as MPS is an experimental component not accessible from
+ * public API.
+ */
+
+/**
+ * \name SECTION: MPS general error codes
+ *
+ * \{
+ */
+
+#ifndef MBEDTLS_MPS_ERR_BASE
+#define MBEDTLS_MPS_ERR_BASE ( 0 )
+#endif
+
+#define MBEDTLS_MPS_MAKE_ERROR(code) \
+ ( -( MBEDTLS_MPS_ERR_BASE | (code) ) )
+
+#define MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED MBEDTLS_MPS_MAKE_ERROR( 0x1 )
+#define MBEDTLS_ERR_MPS_INTERNAL_ERROR MBEDTLS_MPS_MAKE_ERROR( 0x2 )
+
+/* \} name SECTION: MPS general error codes */
+
+/**
+ * \name SECTION: MPS Reader error codes
+ *
+ * \{
+ */
+
+#ifndef MBEDTLS_MPS_READER_ERR_BASE
+#define MBEDTLS_MPS_READER_ERR_BASE ( 1 << 8 )
+#endif
+
+#define MBEDTLS_MPS_READER_MAKE_ERROR(code) \
+ ( -( MBEDTLS_MPS_READER_ERR_BASE | (code) ) )
+
+/*! An attempt to reclaim the data buffer from a reader failed because
+ * the user hasn't yet read and committed all of it. */
+#define MBEDTLS_ERR_MPS_READER_DATA_LEFT MBEDTLS_MPS_READER_MAKE_ERROR( 0x1 )
+
+/*! An invalid argument was passed to the reader. */
+#define MBEDTLS_ERR_MPS_READER_INVALID_ARG MBEDTLS_MPS_READER_MAKE_ERROR( 0x2 )
+
+/*! An attempt to move a reader to consuming mode through mbedtls_mps_reader_feed()
+ * after pausing failed because the provided data is not sufficient to serve the
+ * read requests that led to the pausing. */
+#define MBEDTLS_ERR_MPS_READER_NEED_MORE MBEDTLS_MPS_READER_MAKE_ERROR( 0x3 )
+
+/*! A get request failed because not enough data is available in the reader. */
+#define MBEDTLS_ERR_MPS_READER_OUT_OF_DATA MBEDTLS_MPS_READER_MAKE_ERROR( 0x4 )
+
+/*!< A get request after pausing and reactivating the reader failed because
+ * the request is not in line with the request made prior to pausing. The user
+ * must not change it's 'strategy' after pausing and reactivating a reader. */
+#define MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS MBEDTLS_MPS_READER_MAKE_ERROR( 0x5 )
+
+/*! An attempt to reclaim the data buffer from a reader failed because the reader
+ * has no accumulator it can use to backup the data that hasn't been processed. */
+#define MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR MBEDTLS_MPS_READER_MAKE_ERROR( 0x6 )
+
+/*! An attempt to reclaim the data buffer from a reader failed because the
+ * accumulator passed to the reader is not large enough to hold both the
+ * data that hasn't been processed and the excess of the last read-request. */
+#define MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL MBEDTLS_MPS_READER_MAKE_ERROR( 0x7 )
+
+/* \} name SECTION: MPS Reader error codes */
+
+#endif /* MBEDTLS_MPS_ERROR_H */
diff --git a/thirdparty/mbedtls/library/mps_reader.c b/thirdparty/mbedtls/library/mps_reader.c
new file mode 100644
index 0000000000..9af5073cc9
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_reader.c
@@ -0,0 +1,564 @@
+/*
+ * Message Processing Stack, Reader implementation
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#include "mps_reader.h"
+#include "mps_common.h"
+#include "mps_trace.h"
+
+#include <string.h>
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#if defined(MBEDTLS_MPS_ENABLE_TRACE)
+static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER;
+#endif /* MBEDTLS_MPS_ENABLE_TRACE */
+
+/*
+ * GENERAL NOTE ON CODING STYLE
+ *
+ * The following code intentionally separates memory loads
+ * and stores from other operations (arithmetic or branches).
+ * This leads to the introduction of many local variables
+ * and significantly increases the C-code line count, but
+ * should not increase the size of generated assembly.
+ *
+ * The reason for this is twofold:
+ * (1) It will ease verification efforts using the VST
+ * (Verified Software Toolchain)
+ * whose program logic cannot directly reason
+ * about instructions containing a load or store in
+ * addition to other operations (e.g. *p = *q or
+ * tmp = *p + 42).
+ * (2) Operating on local variables and writing the results
+ * back to the target contexts on success only
+ * allows to maintain structure invariants even
+ * on failure - this in turn has two benefits:
+ * (2.a) If for some reason an error code is not caught
+ * and operation continues, functions are nonetheless
+ * called with sane contexts, reducing the risk
+ * of dangerous behavior.
+ * (2.b) Randomized testing is easier if structures
+ * remain intact even in the face of failing
+ * and/or non-sensical calls.
+ * Moreover, it might even reduce code-size because
+ * the compiler need not write back temporary results
+ * to memory in case of failure.
+ *
+ */
+
+static inline int mps_reader_is_accumulating(
+ mbedtls_mps_reader const *rd )
+{
+ mbedtls_mps_size_t acc_remaining;
+ if( rd->acc == NULL )
+ return( 0 );
+
+ acc_remaining = rd->acc_share.acc_remaining;
+ return( acc_remaining > 0 );
+}
+
+static inline int mps_reader_is_producing(
+ mbedtls_mps_reader const *rd )
+{
+ unsigned char *frag = rd->frag;
+ return( frag == NULL );
+}
+
+static inline int mps_reader_is_consuming(
+ mbedtls_mps_reader const *rd )
+{
+ return( !mps_reader_is_producing( rd ) );
+}
+
+static inline mbedtls_mps_size_t mps_reader_get_fragment_offset(
+ mbedtls_mps_reader const *rd )
+{
+ unsigned char *acc = rd->acc;
+ mbedtls_mps_size_t frag_offset;
+
+ if( acc == NULL )
+ return( 0 );
+
+ frag_offset = rd->acc_share.frag_offset;
+ return( frag_offset );
+}
+
+static inline mbedtls_mps_size_t mps_reader_serving_from_accumulator(
+ mbedtls_mps_reader const *rd )
+{
+ mbedtls_mps_size_t frag_offset, end;
+
+ frag_offset = mps_reader_get_fragment_offset( rd );
+ end = rd->end;
+
+ return( end < frag_offset );
+}
+
+static inline void mps_reader_zero( mbedtls_mps_reader *rd )
+{
+ /* A plain memset() would likely be more efficient,
+ * but the current way of zeroing makes it harder
+ * to overlook fields which should not be zero-initialized.
+ * It's also more suitable for FV efforts since it
+ * doesn't require reasoning about structs being
+ * interpreted as unstructured binary blobs. */
+ static mbedtls_mps_reader const zero =
+ { .frag = NULL,
+ .frag_len = 0,
+ .commit = 0,
+ .end = 0,
+ .pending = 0,
+ .acc = NULL,
+ .acc_len = 0,
+ .acc_available = 0,
+ .acc_share = { .acc_remaining = 0 }
+ };
+ *rd = zero;
+}
+
+int mbedtls_mps_reader_init( mbedtls_mps_reader *rd,
+ unsigned char *acc,
+ mbedtls_mps_size_t acc_len )
+{
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_init" );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "* Accumulator size: %u bytes", (unsigned) acc_len );
+ mps_reader_zero( rd );
+ rd->acc = acc;
+ rd->acc_len = acc_len;
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+int mbedtls_mps_reader_free( mbedtls_mps_reader *rd )
+{
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_free" );
+ mps_reader_zero( rd );
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd,
+ unsigned char *new_frag,
+ mbedtls_mps_size_t new_frag_len )
+{
+ mbedtls_mps_size_t copy_to_acc;
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_feed" );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "* Fragment length: %u bytes", (unsigned) new_frag_len );
+
+ if( new_frag == NULL )
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_INVALID_ARG );
+
+ MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_producing( rd ),
+ "mbedtls_mps_reader_feed() requires reader to be in producing mode" );
+
+ if( mps_reader_is_accumulating( rd ) )
+ {
+ unsigned char *acc = rd->acc;
+ mbedtls_mps_size_t acc_remaining = rd->acc_share.acc_remaining;
+ mbedtls_mps_size_t acc_available = rd->acc_available;
+
+ /* Skip over parts of the accumulator that have already been filled. */
+ acc += acc_available;
+
+ copy_to_acc = acc_remaining;
+ if( copy_to_acc > new_frag_len )
+ copy_to_acc = new_frag_len;
+
+ /* Copy new contents to accumulator. */
+ memcpy( acc, new_frag, copy_to_acc );
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Copy new data of size %u of %u into accumulator at offset %u",
+ (unsigned) copy_to_acc, (unsigned) new_frag_len, (unsigned) acc_available );
+
+ /* Check if, with the new fragment, we have enough data. */
+ acc_remaining -= copy_to_acc;
+ if( acc_remaining > 0 )
+ {
+ /* We need to accumulate more data. Stay in producing mode. */
+ acc_available += copy_to_acc;
+ rd->acc_share.acc_remaining = acc_remaining;
+ rd->acc_available = acc_available;
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE );
+ }
+
+ /* We have filled the accumulator: Move to consuming mode. */
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Enough data available to serve user request" );
+
+ /* Remember overlap of accumulator and fragment. */
+ rd->acc_share.frag_offset = acc_available;
+ acc_available += copy_to_acc;
+ rd->acc_available = acc_available;
+ }
+ else /* Not accumulating */
+ {
+ rd->acc_share.frag_offset = 0;
+ }
+
+ rd->frag = new_frag;
+ rd->frag_len = new_frag_len;
+ rd->commit = 0;
+ rd->end = 0;
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+
+int mbedtls_mps_reader_get( mbedtls_mps_reader *rd,
+ mbedtls_mps_size_t desired,
+ unsigned char **buffer,
+ mbedtls_mps_size_t *buflen )
+{
+ unsigned char *frag;
+ mbedtls_mps_size_t frag_len, frag_offset, end, frag_fetched, frag_remaining;
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_get" );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "* Bytes requested: %u", (unsigned) desired );
+
+ MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ),
+ "mbedtls_mps_reader_get() requires reader to be in consuming mode" );
+
+ end = rd->end;
+ frag_offset = mps_reader_get_fragment_offset( rd );
+
+ /* Check if we're still serving from the accumulator. */
+ if( mps_reader_serving_from_accumulator( rd ) )
+ {
+ /* Illustration of supported and unsupported cases:
+ *
+ * - Allowed #1
+ *
+ * +-----------------------------------+
+ * | frag |
+ * +-----------------------------------+
+ *
+ * end end+desired
+ * | |
+ * +-----v-------v-------------+
+ * | acc |
+ * +---------------------------+
+ * | |
+ * frag_offset acc_available
+ *
+ * - Allowed #2
+ *
+ * +-----------------------------------+
+ * | frag |
+ * +-----------------------------------+
+ *
+ * end end+desired
+ * | |
+ * +----------v----------------v
+ * | acc |
+ * +---------------------------+
+ * | |
+ * frag_offset acc_available
+ *
+ * - Not allowed #1 (could be served, but we don't actually use it):
+ *
+ * +-----------------------------------+
+ * | frag |
+ * +-----------------------------------+
+ *
+ * end end+desired
+ * | |
+ * +------v-------------v------+
+ * | acc |
+ * +---------------------------+
+ * | |
+ * frag_offset acc_available
+ *
+ *
+ * - Not allowed #2 (can't be served with a contiguous buffer):
+ *
+ * +-----------------------------------+
+ * | frag |
+ * +-----------------------------------+
+ *
+ * end end + desired
+ * | |
+ * +------v--------------------+ v
+ * | acc |
+ * +---------------------------+
+ * | |
+ * frag_offset acc_available
+ *
+ * In case of Allowed #2 we're switching to serve from
+ * `frag` starting from the next call to mbedtls_mps_reader_get().
+ */
+
+ unsigned char *acc;
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Serve the request from the accumulator" );
+ if( frag_offset - end < desired )
+ {
+ mbedtls_mps_size_t acc_available;
+ acc_available = rd->acc_available;
+ if( acc_available - end != desired )
+ {
+ /* It might be possible to serve some of these situations by
+ * making additional space in the accumulator, removing those
+ * parts that have already been committed.
+ * On the other hand, this brings additional complexity and
+ * enlarges the code size, while there doesn't seem to be a use
+ * case where we don't attempt exactly the same `get` calls when
+ * resuming on a reader than what we tried before pausing it.
+ * If we believe we adhere to this restricted usage throughout
+ * the library, this check is a good opportunity to
+ * validate this. */
+ MBEDTLS_MPS_TRACE_RETURN(
+ MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS );
+ }
+ }
+
+ acc = rd->acc;
+ acc += end;
+
+ *buffer = acc;
+ if( buflen != NULL )
+ *buflen = desired;
+
+ end += desired;
+ rd->end = end;
+ rd->pending = 0;
+
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+ }
+
+ /* Attempt to serve the request from the current fragment */
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Serve the request from the current fragment." );
+
+ frag_len = rd->frag_len;
+ frag_fetched = end - frag_offset; /* The amount of data from the current
+ * fragment that has already been passed
+ * to the user. */
+ frag_remaining = frag_len - frag_fetched; /* Remaining data in fragment */
+
+ /* Check if we can serve the read request from the fragment. */
+ if( frag_remaining < desired )
+ {
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "There's not enough data in the current fragment "
+ "to serve the request." );
+ /* There's not enough data in the current fragment,
+ * so either just RETURN what we have or fail. */
+ if( buflen == NULL )
+ {
+ if( frag_remaining > 0 )
+ {
+ rd->pending = desired - frag_remaining;
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Remember to collect %u bytes before re-opening",
+ (unsigned) rd->pending );
+ }
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_OUT_OF_DATA );
+ }
+
+ desired = frag_remaining;
+ }
+
+ /* There's enough data in the current fragment to serve the
+ * (potentially modified) read request. */
+
+ frag = rd->frag;
+ frag += frag_fetched;
+
+ *buffer = frag;
+ if( buflen != NULL )
+ *buflen = desired;
+
+ end += desired;
+ rd->end = end;
+ rd->pending = 0;
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+int mbedtls_mps_reader_commit( mbedtls_mps_reader *rd )
+{
+ mbedtls_mps_size_t end;
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_commit" );
+ MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ),
+ "mbedtls_mps_reader_commit() requires reader to be in consuming mode" );
+
+ end = rd->end;
+ rd->commit = end;
+
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd,
+ int *paused )
+{
+ unsigned char *frag, *acc;
+ mbedtls_mps_size_t pending, commit;
+ mbedtls_mps_size_t acc_len, frag_offset, frag_len;
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_reclaim" );
+
+ if( paused != NULL )
+ *paused = 0;
+
+ MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ),
+ "mbedtls_mps_reader_reclaim() requires reader to be in consuming mode" );
+
+ frag = rd->frag;
+ acc = rd->acc;
+ pending = rd->pending;
+ commit = rd->commit;
+ frag_len = rd->frag_len;
+
+ frag_offset = mps_reader_get_fragment_offset( rd );
+
+ if( pending == 0 )
+ {
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "No unsatisfied read-request has been logged." );
+
+ /* Check if there's data left to be consumed. */
+ if( commit < frag_offset || commit - frag_offset < frag_len )
+ {
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "There is data left to be consumed." );
+ rd->end = commit;
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_DATA_LEFT );
+ }
+
+ rd->acc_available = 0;
+ rd->acc_share.acc_remaining = 0;
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Fragment has been fully processed and committed." );
+ }
+ else
+ {
+ int overflow;
+
+ mbedtls_mps_size_t acc_backup_offset;
+ mbedtls_mps_size_t acc_backup_len;
+ mbedtls_mps_size_t frag_backup_offset;
+ mbedtls_mps_size_t frag_backup_len;
+
+ mbedtls_mps_size_t backup_len;
+ mbedtls_mps_size_t acc_len_needed;
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "There has been an unsatisfied read with %u bytes overhead.",
+ (unsigned) pending );
+
+ if( acc == NULL )
+ {
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "No accumulator present" );
+ MBEDTLS_MPS_TRACE_RETURN(
+ MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR );
+ }
+ acc_len = rd->acc_len;
+
+ /* Check if the upper layer has already fetched
+ * and committed the contents of the accumulator. */
+ if( commit < frag_offset )
+ {
+ /* No, accumulator is still being processed. */
+ frag_backup_offset = 0;
+ frag_backup_len = frag_len;
+ acc_backup_offset = commit;
+ acc_backup_len = frag_offset - commit;
+ }
+ else
+ {
+ /* Yes, the accumulator is already processed. */
+ frag_backup_offset = commit - frag_offset;
+ frag_backup_len = frag_len - frag_backup_offset;
+ acc_backup_offset = 0;
+ acc_backup_len = 0;
+ }
+
+ backup_len = acc_backup_len + frag_backup_len;
+ acc_len_needed = backup_len + pending;
+
+ overflow = 0;
+ overflow |= ( backup_len < acc_backup_len );
+ overflow |= ( acc_len_needed < backup_len );
+
+ if( overflow || acc_len < acc_len_needed )
+ {
+ /* Except for the different return code, we behave as if
+ * there hadn't been a call to mbedtls_mps_reader_get()
+ * since the last commit. */
+ rd->end = commit;
+ rd->pending = 0;
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR,
+ "The accumulator is too small to handle the backup." );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR,
+ "* Size: %u", (unsigned) acc_len );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR,
+ "* Needed: %u (%u + %u)",
+ (unsigned) acc_len_needed,
+ (unsigned) backup_len, (unsigned) pending );
+ MBEDTLS_MPS_TRACE_RETURN(
+ MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL );
+ }
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Fragment backup: %u", (unsigned) frag_backup_len );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Accumulator backup: %u", (unsigned) acc_backup_len );
+
+ /* Move uncommitted parts from the accumulator to the front
+ * of the accumulator. */
+ memmove( acc, acc + acc_backup_offset, acc_backup_len );
+
+ /* Copy uncmmitted parts of the current fragment to the
+ * accumulator. */
+ memcpy( acc + acc_backup_len,
+ frag + frag_backup_offset, frag_backup_len );
+
+ rd->acc_available = backup_len;
+ rd->acc_share.acc_remaining = pending;
+
+ if( paused != NULL )
+ *paused = 1;
+ }
+
+ rd->frag = NULL;
+ rd->frag_len = 0;
+
+ rd->commit = 0;
+ rd->end = 0;
+ rd->pending = 0;
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Final state: aa %u, al %u, ar %u",
+ (unsigned) rd->acc_available, (unsigned) rd->acc_len,
+ (unsigned) rd->acc_share.acc_remaining );
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/thirdparty/mbedtls/library/mps_reader.h b/thirdparty/mbedtls/library/mps_reader.h
new file mode 100644
index 0000000000..427c1bd254
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_reader.h
@@ -0,0 +1,382 @@
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/**
+ * \file mps_reader.h
+ *
+ * \brief This file defines reader objects, which together with their
+ * sibling writer objects form the basis for the communication
+ * between the various layers of the Mbed TLS messaging stack,
+ * as well as the communication between the messaging stack and
+ * the (D)TLS handshake protocol implementation.
+ *
+ * Readers provide a means of transferring incoming data from
+ * a 'producer' providing it in chunks of arbitrary size, to
+ * a 'consumer' which fetches and processes it in chunks of
+ * again arbitrary, and potentially different, size.
+ *
+ * Readers can thus be seen as datagram-to-stream converters,
+ * and they abstract away the following two tasks from the user:
+ * 1. The pointer arithmetic of stepping through a producer-
+ * provided chunk in smaller chunks.
+ * 2. The merging of incoming data chunks in case the
+ * consumer requests data in larger chunks than what the
+ * producer provides.
+ *
+ * The basic abstract flow of operation is the following:
+ * - Initially, the reader is in 'producing mode'.
+ * - The producer hands an incoming data buffer to the reader,
+ * moving it from 'producing' to 'consuming' mode.
+ * - The consumer subsequently fetches and processes the buffer
+ * content. Once that's done -- or partially done and a consumer's
+ * request can't be fulfilled -- the producer revokes the reader's
+ * access to the incoming data buffer, putting the reader back to
+ * producing mode.
+ * - The producer subsequently gathers more incoming data and hands
+ * it to the reader until it switches back to consuming mode
+ * if enough data is available for the last consumer request to
+ * be satisfiable.
+ * - Repeat the above.
+ *
+ * The abstract states of the reader from the producer's and
+ * consumer's perspective are as follows:
+ *
+ * - From the perspective of the consumer, the state of the
+ * reader consists of the following:
+ * - A byte stream representing (concatenation of) the data
+ * received through calls to mbedtls_mps_reader_get(),
+ * - A marker within that byte stream indicating which data
+ * can be considered processed, and hence need not be retained,
+ * when the reader is passed back to the producer via
+ * mbedtls_mps_reader_reclaim().
+ * The marker is set via mbedtls_mps_reader_commit()
+ * which places it at the end of the current byte stream.
+ * The consumer need not be aware of the distinction between consumer
+ * and producer mode, because it only interfaces with the reader
+ * when the latter is in consuming mode.
+ *
+ * - From the perspective of the producer, the reader's state is one of:
+ * - Attached: The reader is in consuming mode.
+ * - Unset: No incoming data buffer is currently managed by the reader,
+ * and all previously handed incoming data buffers have been
+ * fully processed. More data needs to be fed into the reader
+ * via mbedtls_mps_reader_feed().
+ *
+ * - Accumulating: No incoming data buffer is currently managed by the
+ * reader, but some data from the previous incoming data
+ * buffer hasn't been processed yet and is internally
+ * held back.
+ * The Attached state belongs to consuming mode, while the Unset and
+ * Accumulating states belong to producing mode.
+ *
+ * Transitioning from the Unset or Accumulating state to Attached is
+ * done via successful calls to mbedtls_mps_reader_feed(), while
+ * transitioning from Attached to either Unset or Accumulating (depending
+ * on what has been processed) is done via mbedtls_mps_reader_reclaim().
+ *
+ * The following diagram depicts the producer-state progression:
+ *
+ * +------------------+ reclaim
+ * | Unset +<-------------------------------------+ get
+ * +--------|---------+ | +------+
+ * | | | |
+ * | | | |
+ * | feed +---------+---+--+ |
+ * +--------------------------------------> <---+
+ * | Attached |
+ * +--------------------------------------> <---+
+ * | feed, enough data available +---------+---+--+ |
+ * | to serve previous consumer request | | |
+ * | | | |
+ * +--------+---------+ | +------+
+ * +----> Accumulating |<-------------------------------------+ commit
+ * | +---+--------------+ reclaim, previous read request
+ * | | couldn't be fulfilled
+ * | |
+ * +--------+
+ * feed, need more data to serve
+ * previous consumer request
+ * |
+ * |
+ * producing mode | consuming mode
+ * |
+ *
+ */
+
+#ifndef MBEDTLS_READER_H
+#define MBEDTLS_READER_H
+
+#include <stdio.h>
+
+#include "mps_common.h"
+#include "mps_error.h"
+
+struct mbedtls_mps_reader;
+typedef struct mbedtls_mps_reader mbedtls_mps_reader;
+
+/*
+ * Structure definitions
+ */
+
+struct mbedtls_mps_reader
+{
+ unsigned char *frag; /*!< The fragment of incoming data managed by
+ * the reader; it is provided to the reader
+ * through mbedtls_mps_reader_feed(). The reader
+ * does not own the fragment and does not
+ * perform any allocation operations on it,
+ * but does have read and write access to it.
+ *
+ * The reader is in consuming mode if
+ * and only if \c frag is not \c NULL. */
+ mbedtls_mps_stored_size_t frag_len;
+ /*!< The length of the current fragment.
+ * Must be 0 if \c frag == \c NULL. */
+ mbedtls_mps_stored_size_t commit;
+ /*!< The offset of the last commit, relative
+ * to the first byte in the fragment, if
+ * no accumulator is present. If an accumulator
+ * is present, it is viewed as a prefix to the
+ * current fragment, and this variable contains
+ * an offset from the beginning of the accumulator.
+ *
+ * This is only used when the reader is in
+ * consuming mode, i.e. \c frag != \c NULL;
+ * otherwise, its value is \c 0. */
+ mbedtls_mps_stored_size_t end;
+ /*!< The offset of the end of the last chunk
+ * passed to the user through a call to
+ * mbedtls_mps_reader_get(), relative to the first
+ * byte in the fragment, if no accumulator is
+ * present. If an accumulator is present, it is
+ * viewed as a prefix to the current fragment, and
+ * this variable contains an offset from the
+ * beginning of the accumulator.
+ *
+ * This is only used when the reader is in
+ * consuming mode, i.e. \c frag != \c NULL;
+ * otherwise, its value is \c 0. */
+ mbedtls_mps_stored_size_t pending;
+ /*!< The amount of incoming data missing on the
+ * last call to mbedtls_mps_reader_get().
+ * In particular, it is \c 0 if the last call
+ * was successful.
+ * If a reader is reclaimed after an
+ * unsuccessful call to mbedtls_mps_reader_get(),
+ * this variable is used to have the reader
+ * remember how much data should be accumulated
+ * so that the call to mbedtls_mps_reader_get()
+ * succeeds next time.
+ * This is only used when the reader is in
+ * consuming mode, i.e. \c frag != \c NULL;
+ * otherwise, its value is \c 0. */
+
+ /* The accumulator is only needed if we need to be able to pause
+ * the reader. A few bytes could be saved by moving this to a
+ * separate struct and using a pointer here. */
+
+ unsigned char *acc; /*!< The accumulator is used to gather incoming
+ * data if a read-request via mbedtls_mps_reader_get()
+ * cannot be served from the current fragment. */
+ mbedtls_mps_stored_size_t acc_len;
+ /*!< The total size of the accumulator. */
+ mbedtls_mps_stored_size_t acc_available;
+ /*!< The number of bytes currently gathered in
+ * the accumulator. This is both used in
+ * producing and in consuming mode:
+ * While producing, it is increased until
+ * it reaches the value of \c acc_remaining below.
+ * While consuming, it is used to judge if a
+ * get request can be served from the
+ * accumulator or not.
+ * Must not be larger than \c acc_len. */
+ union
+ {
+ mbedtls_mps_stored_size_t acc_remaining;
+ /*!< This indicates the amount of data still
+ * to be gathered in the accumulator. It is
+ * only used in producing mode.
+ * Must be at most acc_len - acc_available. */
+ mbedtls_mps_stored_size_t frag_offset;
+ /*!< If an accumulator is present and in use, this
+ * field indicates the offset of the current
+ * fragment from the beginning of the
+ * accumulator. If no accumulator is present
+ * or the accumulator is not in use, this is \c 0.
+ * It is only used in consuming mode.
+ * Must not be larger than \c acc_available. */
+ } acc_share;
+};
+
+/*
+ * API organization:
+ * A reader object is usually prepared and maintained
+ * by some lower layer and passed for usage to an upper
+ * layer, and the API naturally splits according to which
+ * layer is supposed to use the respective functions.
+ */
+
+/*
+ * Maintenance API (Lower layer)
+ */
+
+/**
+ * \brief Initialize a reader object
+ *
+ * \param reader The reader to be initialized.
+ * \param acc The buffer to be used as a temporary accumulator
+ * in case get requests through mbedtls_mps_reader_get()
+ * exceed the buffer provided by mbedtls_mps_reader_feed().
+ * This buffer is owned by the caller and exclusive use
+ * for reading and writing is given to the reader for the
+ * duration of the reader's lifetime. It is thus the caller's
+ * responsibility to maintain (and not touch) the buffer for
+ * the lifetime of the reader, and to properly zeroize and
+ * free the memory after the reader has been destroyed.
+ * \param acc_len The size in Bytes of \p acc.
+ *
+ * \return \c 0 on success.
+ * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
+ */
+int mbedtls_mps_reader_init( mbedtls_mps_reader *reader,
+ unsigned char *acc,
+ mbedtls_mps_size_t acc_len );
+
+/**
+ * \brief Free a reader object
+ *
+ * \param reader The reader to be freed.
+ *
+ * \return \c 0 on success.
+ * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
+ */
+int mbedtls_mps_reader_free( mbedtls_mps_reader *reader );
+
+/**
+ * \brief Pass chunk of data for the reader to manage.
+ *
+ * \param reader The reader context to use. The reader must be
+ * in producing mode.
+ * \param buf The buffer to be managed by the reader.
+ * \param buflen The size in Bytes of \p buffer.
+ *
+ * \return \c 0 on success. In this case, the reader will be
+ * moved to consuming mode and obtains read access
+ * of \p buf until mbedtls_mps_reader_reclaim()
+ * is called. It is the responsibility of the caller
+ * to ensure that the \p buf persists and is not changed
+ * between successful calls to mbedtls_mps_reader_feed()
+ * and mbedtls_mps_reader_reclaim().
+ * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
+ * required to fulfill a previous request to mbedtls_mps_reader_get().
+ * In this case, the reader remains in producing mode and
+ * takes no ownership of the provided buffer (an internal copy
+ * is made instead).
+ * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
+ * different kinds of failures.
+ */
+int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader,
+ unsigned char *buf,
+ mbedtls_mps_size_t buflen );
+
+/**
+ * \brief Reclaim reader's access to the current input buffer.
+ *
+ * \param reader The reader context to use. The reader must be
+ * in consuming mode.
+ * \param paused If not \c NULL, the integer at address \p paused will be
+ * modified to indicate whether the reader has been paused
+ * (value \c 1) or not (value \c 0). Pausing happens if there
+ * is uncommitted data and a previous request to
+ * mbedtls_mps_reader_get() has exceeded the bounds of the
+ * input buffer.
+ *
+ * \return \c 0 on success.
+ * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
+ */
+int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader,
+ int *paused );
+
+/*
+ * Usage API (Upper layer)
+ */
+
+/**
+ * \brief Request data from the reader.
+ *
+ * \param reader The reader context to use. The reader must
+ * be in consuming mode.
+ * \param desired The desired amount of data to be read, in Bytes.
+ * \param buffer The address to store the buffer pointer in.
+ * This must not be \c NULL.
+ * \param buflen The address to store the actual buffer
+ * length in, or \c NULL.
+ *
+ * \return \c 0 on success. In this case, \c *buf holds the
+ * address of a buffer of size \c *buflen
+ * (if \c buflen != \c NULL) or \c desired
+ * (if \c buflen == \c NULL). The user has read access
+ * to the buffer and guarantee of stability of the data
+ * until the next call to mbedtls_mps_reader_reclaim().
+ * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
+ * data available to serve the get request. In this case, the
+ * reader remains intact and in consuming mode, and the consumer
+ * should retry the call after a successful cycle of
+ * mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed().
+ * If, after such a cycle, the consumer requests a different
+ * amount of data, the result is implementation-defined;
+ * progress is guaranteed only if the same amount of data
+ * is requested after a mbedtls_mps_reader_reclaim() and
+ * mbedtls_mps_reader_feed() cycle.
+ * \return Another negative \c MBEDTLS_ERR_READER_XXX error
+ * code for different kinds of failure.
+ *
+ * \note Passing \c NULL as \p buflen is a convenient way to
+ * indicate that fragmentation is not tolerated.
+ * It's functionally equivalent to passing a valid
+ * address as buflen and checking \c *buflen == \c desired
+ * afterwards.
+ */
+int mbedtls_mps_reader_get( mbedtls_mps_reader *reader,
+ mbedtls_mps_size_t desired,
+ unsigned char **buffer,
+ mbedtls_mps_size_t *buflen );
+
+/**
+ * \brief Mark data obtained from mbedtls_mps_reader_get() as processed.
+ *
+ * This call indicates that all data received from prior calls to
+ * mbedtls_mps_reader_get() has been or will have been
+ * processed when mbedtls_mps_reader_reclaim() is called,
+ * and thus need not be backed up.
+ *
+ * This function has no user observable effect until
+ * mbedtls_mps_reader_reclaim() is called. In particular,
+ * buffers received from mbedtls_mps_reader_get() remain
+ * valid until mbedtls_mps_reader_reclaim() is called.
+ *
+ * \param reader The reader context to use.
+ *
+ * \return \c 0 on success.
+ * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
+ *
+ */
+int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader );
+
+#endif /* MBEDTLS_READER_H */
diff --git a/thirdparty/mbedtls/library/mps_trace.c b/thirdparty/mbedtls/library/mps_trace.c
new file mode 100644
index 0000000000..6026a07163
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_trace.c
@@ -0,0 +1,127 @@
+/*
+ * Message Processing Stack, Trace module
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#include "mps_common.h"
+
+#if defined(MBEDTLS_MPS_ENABLE_TRACE)
+
+#include "mps_trace.h"
+#include <stdarg.h>
+
+static int trace_depth = 0;
+
+#define color_default "\x1B[0m"
+#define color_red "\x1B[1;31m"
+#define color_green "\x1B[1;32m"
+#define color_yellow "\x1B[1;33m"
+#define color_blue "\x1B[1;34m"
+#define color_magenta "\x1B[1;35m"
+#define color_cyan "\x1B[1;36m"
+#define color_white "\x1B[1;37m"
+
+static char const * colors[] =
+{
+ color_default,
+ color_green,
+ color_yellow,
+ color_magenta,
+ color_cyan,
+ color_blue,
+ color_white
+};
+
+#define MPS_TRACE_BUF_SIZE 100
+
+void mbedtls_mps_trace_print_msg( int id, int line, const char *format, ... )
+{
+ int ret;
+ char str[MPS_TRACE_BUF_SIZE];
+ va_list argp;
+ va_start( argp, format );
+ ret = mbedtls_vsnprintf( str, MPS_TRACE_BUF_SIZE, format, argp );
+ va_end( argp );
+
+ if( ret >= 0 && ret < MPS_TRACE_BUF_SIZE )
+ {
+ str[ret] = '\0';
+ mbedtls_printf( "[%d|L%d]: %s\n", id, line, str );
+ }
+}
+
+int mbedtls_mps_trace_get_depth()
+{
+ return trace_depth;
+}
+void mbedtls_mps_trace_dec_depth()
+{
+ trace_depth--;
+}
+void mbedtls_mps_trace_inc_depth()
+{
+ trace_depth++;
+}
+
+void mbedtls_mps_trace_color( int id )
+{
+ if( id > (int) ( sizeof( colors ) / sizeof( *colors ) ) )
+ return;
+ printf( "%s", colors[ id ] );
+}
+
+void mbedtls_mps_trace_indent( int level, mbedtls_mps_trace_type ty )
+{
+ if( level > 0 )
+ {
+ while( --level )
+ printf( "| " );
+
+ printf( "| " );
+ }
+
+ switch( ty )
+ {
+ case MBEDTLS_MPS_TRACE_TYPE_COMMENT:
+ mbedtls_printf( "@ " );
+ break;
+
+ case MBEDTLS_MPS_TRACE_TYPE_CALL:
+ mbedtls_printf( "+--> " );
+ break;
+
+ case MBEDTLS_MPS_TRACE_TYPE_ERROR:
+ mbedtls_printf( "E " );
+ break;
+
+ case MBEDTLS_MPS_TRACE_TYPE_RETURN:
+ mbedtls_printf( "< " );
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif /* MBEDTLS_MPS_ENABLE_TRACE */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/thirdparty/mbedtls/library/mps_trace.h b/thirdparty/mbedtls/library/mps_trace.h
new file mode 100644
index 0000000000..7c2360118a
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_trace.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/**
+ * \file mps_trace.h
+ *
+ * \brief Tracing module for MPS
+ */
+
+#ifndef MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H
+#define MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H
+
+#include "common.h"
+#include "mps_common.h"
+#include "mps_trace.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#define mbedtls_vsnprintf vsnprintf
+#endif /* MBEDTLS_PLATFORM_C */
+
+#if defined(MBEDTLS_MPS_ENABLE_TRACE)
+
+/*
+ * Adapt this to enable/disable tracing output
+ * from the various layers of the MPS.
+ */
+
+#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_1
+#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_2
+#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_3
+#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_4
+#define MBEDTLS_MPS_TRACE_ENABLE_READER
+#define MBEDTLS_MPS_TRACE_ENABLE_WRITER
+
+/*
+ * To use the existing trace module, only change
+ * MBEDTLS_MPS_TRACE_ENABLE_XXX above, but don't modify the
+ * rest of this file.
+ */
+
+typedef enum
+{
+ MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ MBEDTLS_MPS_TRACE_TYPE_CALL,
+ MBEDTLS_MPS_TRACE_TYPE_ERROR,
+ MBEDTLS_MPS_TRACE_TYPE_RETURN
+} mbedtls_mps_trace_type;
+
+#define MBEDTLS_MPS_TRACE_BIT_LAYER_1 1
+#define MBEDTLS_MPS_TRACE_BIT_LAYER_2 2
+#define MBEDTLS_MPS_TRACE_BIT_LAYER_3 3
+#define MBEDTLS_MPS_TRACE_BIT_LAYER_4 4
+#define MBEDTLS_MPS_TRACE_BIT_WRITER 5
+#define MBEDTLS_MPS_TRACE_BIT_READER 6
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_1)
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_1 )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_2)
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_2 )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_3)
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_3 )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_4)
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_4 )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_READER)
+#define MBEDTLS_MPS_TRACE_MASK_READER (1u << MBEDTLS_MPS_TRACE_BIT_READER )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_READER 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_WRITER)
+#define MBEDTLS_MPS_TRACE_MASK_WRITER (1u << MBEDTLS_MPS_TRACE_BIT_WRITER )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_WRITER 0
+#endif
+
+#define MBEDTLS_MPS_TRACE_MASK ( MBEDTLS_MPS_TRACE_MASK_LAYER_1 | \
+ MBEDTLS_MPS_TRACE_MASK_LAYER_2 | \
+ MBEDTLS_MPS_TRACE_MASK_LAYER_3 | \
+ MBEDTLS_MPS_TRACE_MASK_LAYER_4 | \
+ MBEDTLS_MPS_TRACE_MASK_READER | \
+ MBEDTLS_MPS_TRACE_MASK_WRITER )
+
+/* We have to avoid globals because E-ACSL chokes on them...
+ * Wrap everything in stub functions. */
+int mbedtls_mps_trace_get_depth( void );
+void mbedtls_mps_trace_inc_depth( void );
+void mbedtls_mps_trace_dec_depth( void );
+
+void mbedtls_mps_trace_color( int id );
+void mbedtls_mps_trace_indent( int level, mbedtls_mps_trace_type ty );
+
+void mbedtls_mps_trace_print_msg( int id, int line, const char *format, ... );
+
+#define MBEDTLS_MPS_TRACE( type, ... ) \
+ do { \
+ if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \
+ break; \
+ mbedtls_mps_trace_indent( mbedtls_mps_trace_get_depth(), type ); \
+ mbedtls_mps_trace_color( mbedtls_mps_trace_id ); \
+ mbedtls_mps_trace_print_msg( mbedtls_mps_trace_id, __LINE__, __VA_ARGS__ ); \
+ mbedtls_mps_trace_color( 0 ); \
+ } while( 0 )
+
+#define MBEDTLS_MPS_TRACE_INIT( ... ) \
+ do { \
+ if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \
+ break; \
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_CALL, __VA_ARGS__ ); \
+ mbedtls_mps_trace_inc_depth(); \
+ } while( 0 )
+
+#define MBEDTLS_MPS_TRACE_END( val ) \
+ do { \
+ if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \
+ break; \
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_RETURN, "%d (-%#04x)", \
+ (int) (val), -((unsigned)(val)) ); \
+ mbedtls_mps_trace_dec_depth(); \
+ } while( 0 )
+
+#define MBEDTLS_MPS_TRACE_RETURN( val ) \
+ do { \
+ /* Breaks tail recursion. */ \
+ int ret__ = val; \
+ MBEDTLS_MPS_TRACE_END( ret__ ); \
+ return( ret__ ); \
+ } while( 0 )
+
+#else /* MBEDTLS_MPS_TRACE */
+
+#define MBEDTLS_MPS_TRACE( type, ... ) do { } while( 0 )
+#define MBEDTLS_MPS_TRACE_INIT( ... ) do { } while( 0 )
+#define MBEDTLS_MPS_TRACE_END do { } while( 0 )
+
+#define MBEDTLS_MPS_TRACE_RETURN( val ) return( val );
+
+#endif /* MBEDTLS_MPS_TRACE */
+
+#endif /* MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H */
diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c
index 1e701a5000..5fbe1f764a 100644
--- a/thirdparty/mbedtls/library/net_sockets.c
+++ b/thirdparty/mbedtls/library/net_sockets.c
@@ -2,13 +2,7 @@
* TCP/IP or UDP/IP networking functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
@@ -50,24 +23,17 @@
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#endif
-
-#if defined(__NetBSD__)
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600 /* sockaddr_storage */
#endif
-#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_NET_C)
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
- !defined(__HAIKU__)
+ !defined(__HAIKU__) && !defined(__midipix__)
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
#endif
@@ -78,6 +44,7 @@
#endif
#include "mbedtls/net_sockets.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -86,8 +53,7 @@
#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR )
-#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
-#undef _WIN32_WINNT
+#if !defined(_WIN32_WINNT)
/* Enables getaddrinfo() & Co */
#define _WIN32_WINNT 0x0501
#endif
@@ -96,6 +62,9 @@
#include <winsock2.h>
#include <windows.h>
+#if (_WIN32_WINNT < 0x0501)
+#include <wspiapi.h>
+#endif
#if defined(_MSC_VER)
#if defined(_WIN32_WCE)
@@ -205,7 +174,7 @@ void mbedtls_net_init( mbedtls_net_context *ctx )
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host,
const char *port, int proto )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
struct addrinfo hints, *addr_list, *cur;
if( ( ret = net_prepare() ) != 0 )
@@ -371,14 +340,14 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
mbedtls_net_context *client_ctx,
void *client_ip, size_t buf_size, size_t *ip_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int type;
struct sockaddr_storage client_addr;
-#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
+#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \
- ( defined(__NetBSD__) && defined(socklen_t) )
+ defined(socklen_t) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L)
socklen_t n = (socklen_t) sizeof( client_addr );
socklen_t type_len = (socklen_t) sizeof( type );
#else
@@ -514,7 +483,7 @@ int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
struct timeval tv;
fd_set read_fds;
@@ -600,7 +569,7 @@ void mbedtls_net_usleep( unsigned long usec )
*/
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int fd = ((mbedtls_net_context *) ctx)->fd;
ret = check_fd( fd, 0 );
@@ -638,7 +607,7 @@ int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
size_t len, uint32_t timeout )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
struct timeval tv;
fd_set read_fds;
int fd = ((mbedtls_net_context *) ctx)->fd;
@@ -682,7 +651,7 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
*/
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int fd = ((mbedtls_net_context *) ctx)->fd;
ret = check_fd( fd, 0 );
@@ -715,6 +684,19 @@ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
}
/*
+ * Close the connection
+ */
+void mbedtls_net_close( mbedtls_net_context *ctx )
+{
+ if( ctx->fd == -1 )
+ return;
+
+ close( ctx->fd );
+
+ ctx->fd = -1;
+}
+
+/*
* Gracefully close the connection
*/
void mbedtls_net_free( mbedtls_net_context *ctx )
diff --git a/thirdparty/mbedtls/library/nist_kw.c b/thirdparty/mbedtls/library/nist_kw.c
index 278b7e91ab..1aea0b6345 100644
--- a/thirdparty/mbedtls/library/nist_kw.c
+++ b/thirdparty/mbedtls/library/nist_kw.c
@@ -3,13 +3,7 @@
* only
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -22,27 +16,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* Definition of Key Wrapping:
@@ -54,16 +27,14 @@
* the wrapping and unwrapping operation than the definition in NIST SP 800-38F.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_NIST_KW_C)
#include "mbedtls/nist_kw.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
#include <stdint.h>
#include <string.h>
@@ -82,51 +53,11 @@
#define KW_SEMIBLOCK_LENGTH 8
#define MIN_SEMIBLOCKS_COUNT 3
-/* constant-time buffer comparison */
-static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n )
-{
- size_t i;
- volatile const unsigned char *A = (volatile const unsigned char *) a;
- volatile const unsigned char *B = (volatile const unsigned char *) b;
- volatile unsigned char diff = 0;
-
- for( i = 0; i < n; i++ )
- {
- /* Read volatile data in order before computing diff.
- * This avoids IAR compiler warning:
- * 'the order of volatile accesses is undefined ..' */
- unsigned char x = A[i], y = B[i];
- diff |= x ^ y;
- }
-
- return( diff );
-}
-
/*! The 64-bit default integrity check value (ICV) for KW mode. */
static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
/*! The 32-bit default integrity check value (ICV) for KWP mode. */
static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6};
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-do { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-} while( 0 )
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-do { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-} while( 0 )
-#endif
-
/*
* Initialize context
*/
@@ -141,7 +72,7 @@ int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx,
unsigned int keybits,
const int is_wrap )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values( cipher,
@@ -273,7 +204,7 @@ int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx,
}
memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 );
- PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
+ MBEDTLS_PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
KW_SEMIBLOCK_LENGTH / 2 );
memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len );
@@ -448,7 +379,7 @@ int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx,
goto cleanup;
/* Check ICV in "constant-time" */
- diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
+ diff = mbedtls_ct_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
if( diff != 0 )
{
@@ -497,14 +428,14 @@ int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx,
}
/* Check ICV in "constant-time" */
- diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
+ diff = mbedtls_ct_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
if( diff != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
}
- GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 );
+ Plen = MBEDTLS_GET_UINT32_BE( A, KW_SEMIBLOCK_LENGTH / 2 );
/*
* Plen is the length of the plaintext, when the input is valid.
diff --git a/thirdparty/mbedtls/library/oid.c b/thirdparty/mbedtls/library/oid.c
index 2414083f0c..19c8ac207c 100644
--- a/thirdparty/mbedtls/library/oid.c
+++ b/thirdparty/mbedtls/library/oid.c
@@ -4,13 +4,7 @@
* \brief Object Identifier (OID) database
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,39 +17,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_OID_C)
#include "mbedtls/oid.h"
#include "mbedtls/rsa.h"
+#include "mbedtls/error.h"
#include <stdio.h>
#include <string.h>
@@ -66,10 +36,6 @@
#define mbedtls_snprintf snprintf
#endif
-#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
-#include "mbedtls/x509.h"
-#endif
-
/*
* Macro to automatically add the size of #define'd OIDs
*/
@@ -180,7 +146,6 @@ int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
return( MBEDTLS_ERR_OID_NOT_FOUND ); \
}
-#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
/*
* For X520 attribute types
*/
@@ -287,24 +252,28 @@ typedef struct {
static const oid_x509_ext_t oid_x509_ext[] =
{
{
- { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
- MBEDTLS_X509_EXT_BASIC_CONSTRAINTS,
+ { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
+ MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS,
+ },
+ {
+ { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
+ MBEDTLS_OID_X509_EXT_KEY_USAGE,
},
{
- { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
- MBEDTLS_X509_EXT_KEY_USAGE,
+ { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
+ MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE,
},
{
- { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
- MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE,
+ { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
+ MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME,
},
{
- { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
- MBEDTLS_X509_EXT_SUBJECT_ALT_NAME,
+ { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
+ MBEDTLS_OID_X509_EXT_NS_CERT_TYPE,
},
{
- { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
- MBEDTLS_X509_EXT_NS_CERT_TYPE,
+ { ADD_LEN( MBEDTLS_OID_CERTIFICATE_POLICIES ), "id-ce-certificatePolicies", "Certificate Policies" },
+ MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES,
},
{
{ NULL, 0, NULL, NULL },
@@ -317,18 +286,27 @@ FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, e
static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
{
- { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
- { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
- { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
- { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
- { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
- { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
+ { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
+ { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
+ { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
+ { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
+ { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
+ { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
+ { ADD_LEN( MBEDTLS_OID_WISUN_FAN ), "id-kp-wisun-fan-device", "Wi-SUN Alliance Field Area Network (FAN)" },
{ NULL, 0, NULL, NULL },
};
FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage)
FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description)
-#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
+
+static const mbedtls_oid_descriptor_t oid_certificate_policies[] =
+{
+ { ADD_LEN( MBEDTLS_OID_ANY_POLICY ), "anyPolicy", "Any Policy" },
+ { NULL, 0, NULL, NULL },
+};
+
+FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, certificate_policies, oid_certificate_policies)
+FN_OID_GET_ATTR1(mbedtls_oid_get_certificate_policies, mbedtls_oid_descriptor_t, certificate_policies, const char *, description)
#if defined(MBEDTLS_MD_C)
/*
@@ -644,6 +622,12 @@ static const oid_md_alg_t oid_md_alg[] =
MBEDTLS_MD_SHA512,
},
#endif /* MBEDTLS_SHA512_C */
+#if defined(MBEDTLS_RIPEMD160_C)
+ {
+ { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_RIPEMD160 ), "id-ripemd160", "RIPEMD-160" },
+ MBEDTLS_MD_RIPEMD160,
+ },
+#endif /* MBEDTLS_RIPEMD160_C */
{
{ NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE,
@@ -743,7 +727,7 @@ FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pb
int mbedtls_oid_get_numeric_string( char *buf, size_t size,
const mbedtls_asn1_buf *oid )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n;
unsigned int value;
char *p;
@@ -771,7 +755,7 @@ int mbedtls_oid_get_numeric_string( char *buf, size_t size,
if( !( oid->p[i] & 0x80 ) )
{
/* Last byte */
- ret = mbedtls_snprintf( p, n, ".%d", value );
+ ret = mbedtls_snprintf( p, n, ".%u", value );
OID_SAFE_SNPRINTF;
value = 0;
}
diff --git a/thirdparty/mbedtls/library/padlock.c b/thirdparty/mbedtls/library/padlock.c
index afb7e0ad42..837337413c 100644
--- a/thirdparty/mbedtls/library/padlock.c
+++ b/thirdparty/mbedtls/library/padlock.c
@@ -2,13 +2,7 @@
* VIA PadLock support functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* This implementation is based on the VIA PadLock Programming Guide:
@@ -50,11 +23,7 @@
* programming_guide.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PADLOCK_C)
@@ -83,10 +52,10 @@ int mbedtls_padlock_has_support( int feature )
"cpuid \n\t"
"cmpl $0xC0000001, %%eax \n\t"
"movl $0, %%edx \n\t"
- "jb unsupported \n\t"
+ "jb 1f \n\t"
"movl $0xC0000001, %%eax \n\t"
"cpuid \n\t"
- "unsupported: \n\t"
+ "1: \n\t"
"movl %%edx, %1 \n\t"
"movl %2, %%ebx \n\t"
: "=m" (ebx), "=m" (edx)
diff --git a/thirdparty/mbedtls/library/pem.c b/thirdparty/mbedtls/library/pem.c
index 50e663ccdb..fcfde94799 100644
--- a/thirdparty/mbedtls/library/pem.c
+++ b/thirdparty/mbedtls/library/pem.c
@@ -2,13 +2,7 @@
* Privacy Enhanced Mail (PEM) decoding
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
@@ -59,6 +28,7 @@
#include "mbedtls/md5.h"
#include "mbedtls/cipher.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -110,7 +80,7 @@ static int pem_pbkdf1( unsigned char *key, size_t keylen,
mbedtls_md5_context md5_ctx;
unsigned char md5sum[16];
size_t use_len;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md5_init( &md5_ctx );
@@ -171,7 +141,7 @@ static int pem_des_decrypt( unsigned char des_iv[8],
{
mbedtls_des_context des_ctx;
unsigned char des_key[8];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_des_init( &des_ctx );
@@ -199,7 +169,7 @@ static int pem_des3_decrypt( unsigned char des3_iv[8],
{
mbedtls_des3_context des3_ctx;
unsigned char des3_key[24];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_des3_init( &des3_ctx );
@@ -229,7 +199,7 @@ static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
{
mbedtls_aes_context aes_ctx;
unsigned char aes_key[32];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_aes_init( &aes_ctx );
@@ -373,7 +343,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 );
if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
- return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PEM_INVALID_DATA, ret ) );
if( ( buf = mbedtls_calloc( 1, len ) ) == NULL )
return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
@@ -382,7 +352,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
{
mbedtls_platform_zeroize( buf, len );
mbedtls_free( buf );
- return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PEM_INVALID_DATA, ret ) );
}
if( enc != 0 )
@@ -464,7 +434,7 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
const unsigned char *der_data, size_t der_len,
unsigned char *buf, size_t buf_len, size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *encode_buf = NULL, *c, *p = buf;
size_t len = 0, use_len, add_len = 0;
diff --git a/thirdparty/mbedtls/library/pk.c b/thirdparty/mbedtls/library/pk.c
index 8998271b97..05cc2134f1 100644
--- a/thirdparty/mbedtls/library/pk.c
+++ b/thirdparty/mbedtls/library/pk.c
@@ -2,13 +2,7 @@
* Public Key abstraction layer
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,40 +15,16 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PK_C)
#include "mbedtls/pk.h"
#include "mbedtls/pk_internal.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
@@ -66,6 +36,10 @@
#include "mbedtls/ecdsa.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#endif
+
#include <limits.h>
#include <stdint.h>
@@ -172,6 +146,42 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
return( 0 );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/*
+ * Initialise a PSA-wrapping context
+ */
+int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
+ const psa_key_id_t key )
+{
+ const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t *pk_ctx;
+ psa_key_type_t type;
+
+ if( ctx == NULL || ctx->pk_info != NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+ type = psa_get_key_type( &attributes );
+ psa_reset_key_attributes( &attributes );
+
+ /* Current implementation of can_do() relies on this. */
+ if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ;
+
+ if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
+ return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+ ctx->pk_info = info;
+
+ pk_ctx = (psa_key_id_t *) ctx->pk_ctx;
+ *pk_ctx = key;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/*
* Initialize an RSA-alt context
@@ -231,7 +241,7 @@ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len
if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
return( -1 );
- if ( *hash_len != 0 && *hash_len < mbedtls_md_get_size( md_info ) )
+ if ( *hash_len != 0 && *hash_len != mbedtls_md_get_size( md_info ) )
return ( -1 );
*hash_len = mbedtls_md_get_size( md_info );
@@ -286,7 +296,7 @@ int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
mbedtls_ecp_restart_is_enabled() &&
ctx->pk_info->verify_rs_func != NULL )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
return( ret );
@@ -343,7 +353,7 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
if( type == MBEDTLS_PK_RSASSA_PSS )
{
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_pk_rsassa_pss_options *pss_opts;
#if SIZE_MAX > UINT_MAX
@@ -409,7 +419,7 @@ int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
mbedtls_ecp_restart_is_enabled() &&
ctx->pk_info->sign_rs_func != NULL )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
return( ret );
@@ -500,12 +510,14 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte
PK_VALIDATE_RET( prv != NULL );
if( pub->pk_info == NULL ||
- prv->pk_info == NULL ||
- prv->pk_info->check_pair_func == NULL )
+ prv->pk_info == NULL )
{
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
}
+ if( prv->pk_info->check_pair_func == NULL )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
{
if( pub->pk_info->type != MBEDTLS_PK_RSA )
@@ -571,4 +583,60 @@ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
return( ctx->pk_info->type );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/*
+ * Load the key to a PSA key slot,
+ * then turn the PK context into a wrapper for that key slot.
+ *
+ * Currently only works for EC private keys.
+ */
+int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
+ psa_key_id_t *key,
+ psa_algorithm_t hash_alg )
+{
+#if !defined(MBEDTLS_ECP_C)
+ ((void) pk);
+ ((void) key);
+ ((void) hash_alg);
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+#else
+ const mbedtls_ecp_keypair *ec;
+ unsigned char d[MBEDTLS_ECP_MAX_BYTES];
+ size_t d_len;
+ psa_ecc_family_t curve_id;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t key_type;
+ size_t bits;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* export the private key material in the format PSA wants */
+ if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+ ec = mbedtls_pk_ec( *pk );
+ d_len = ( ec->grp.nbits + 7 ) / 8;
+ if( ( ret = mbedtls_mpi_write_binary( &ec->d, d, d_len ) ) != 0 )
+ return( ret );
+
+ curve_id = mbedtls_ecc_group_to_psa( ec->grp.id, &bits );
+ key_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve_id );
+
+ /* prepare the key attributes */
+ psa_set_key_type( &attributes, key_type );
+ psa_set_key_bits( &attributes, bits );
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
+ psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(hash_alg) );
+
+ /* import private key into PSA */
+ if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, key ) )
+ return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+
+ /* make PK context wrap the key slot */
+ mbedtls_pk_free( pk );
+ mbedtls_pk_init( pk );
+
+ return( mbedtls_pk_setup_opaque( pk, *key ) );
+#endif /* MBEDTLS_ECP_C */
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_PK_C */
diff --git a/thirdparty/mbedtls/library/pk_wrap.c b/thirdparty/mbedtls/library/pk_wrap.c
index 2c27552d9b..107e912ace 100644
--- a/thirdparty/mbedtls/library/pk_wrap.c
+++ b/thirdparty/mbedtls/library/pk_wrap.c
@@ -2,13 +2,7 @@
* Public Key abstraction layer: wrapper functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,37 +15,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PK_C)
#include "mbedtls/pk_internal.h"
+#include "mbedtls/error.h"
/* Even if RSA not activated, for the sake of RSA-alt */
#include "mbedtls/rsa.h"
@@ -66,10 +36,20 @@
#include "mbedtls/ecdsa.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/asn1write.h"
+#endif
+
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
#include "mbedtls/platform_util.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#include "mbedtls/asn1.h"
+#endif
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -98,7 +78,7 @@ static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
size_t rsa_len = mbedtls_rsa_get_len( rsa );
@@ -263,7 +243,7 @@ static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init( &ecdsa );
@@ -281,7 +261,7 @@ static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init( &ecdsa );
@@ -355,7 +335,7 @@ static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *sig, size_t sig_len,
void *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
eckey_restart_ctx *rs = rs_ctx;
/* Should never happen */
@@ -380,7 +360,7 @@ static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
void *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
eckey_restart_ctx *rs = rs_ctx;
/* Should never happen */
@@ -497,11 +477,153 @@ static int ecdsa_can_do( mbedtls_pk_type_t type )
return( type == MBEDTLS_PK_ECDSA );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/*
+ * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
+ * those integers and convert it to the fixed-length encoding expected by PSA.
+ */
+static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end,
+ unsigned char *to, size_t to_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t unpadded_len, padding_len;
+
+ if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len,
+ MBEDTLS_ASN1_INTEGER ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ while( unpadded_len > 0 && **from == 0x00 )
+ {
+ ( *from )++;
+ unpadded_len--;
+ }
+
+ if( unpadded_len > to_len || unpadded_len == 0 )
+ return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ padding_len = to_len - unpadded_len;
+ memset( to, 0x00, padding_len );
+ memcpy( to + padding_len, *from, unpadded_len );
+ ( *from ) += unpadded_len;
+
+ return( 0 );
+}
+
+/*
+ * Convert a signature from an ASN.1 sequence of two integers
+ * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
+ * twice as big as int_size.
+ */
+static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end,
+ unsigned char *sig, size_t int_size )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t tmp_size;
+
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( ret );
+
+ /* Extract r */
+ if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 )
+ return( ret );
+ /* Extract s */
+ if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 )
+ return( ret );
+
+ return( 0 );
+}
+
+static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ mbedtls_ecdsa_context *ctx = ctx_arg;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id = 0;
+ psa_status_t status;
+ mbedtls_pk_context key;
+ int key_len;
+ /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */
+ unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES];
+ unsigned char *p;
+ mbedtls_pk_info_t pk_info = mbedtls_eckey_info;
+ psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
+ size_t curve_bits;
+ psa_ecc_family_t curve =
+ mbedtls_ecc_group_to_psa( ctx->grp.id, &curve_bits );
+ const size_t signature_part_size = ( ctx->grp.nbits + 7 ) / 8;
+ ((void) md_alg);
+
+ if( curve == 0 )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ /* mbedtls_pk_write_pubkey() expects a full PK context;
+ * re-construct one to make it happy */
+ key.pk_info = &pk_info;
+ key.pk_ctx = ctx;
+ p = buf + sizeof( buf );
+ key_len = mbedtls_pk_write_pubkey( &p, buf, &key );
+ if( key_len <= 0 )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ psa_set_key_type( &attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ) );
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
+ psa_set_key_algorithm( &attributes, psa_sig_md );
+
+ status = psa_import_key( &attributes,
+ buf + sizeof( buf ) - key_len, key_len,
+ &key_id );
+ if( status != PSA_SUCCESS )
+ {
+ ret = mbedtls_psa_err_translate_pk( status );
+ goto cleanup;
+ }
+
+ /* We don't need the exported key anymore and can
+ * reuse its buffer for signature extraction. */
+ if( 2 * signature_part_size > sizeof( buf ) )
+ {
+ ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ goto cleanup;
+ }
+
+ p = (unsigned char*) sig;
+ if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf,
+ signature_part_size ) ) != 0 )
+ {
+ goto cleanup;
+ }
+
+ if( psa_verify_hash( key_id, psa_sig_md,
+ hash, hash_len,
+ buf, 2 * signature_part_size )
+ != PSA_SUCCESS )
+ {
+ ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
+ goto cleanup;
+ }
+
+ if( p != sig + sig_len )
+ {
+ ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
+ goto cleanup;
+ }
+ ret = 0;
+
+cleanup:
+ psa_destroy_key( key_id );
+ return( ret );
+}
+#else /* MBEDTLS_USE_PSA_CRYPTO */
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
((void) md_alg);
ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
@@ -512,6 +634,7 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
return( ret );
}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
@@ -528,7 +651,7 @@ static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *sig, size_t sig_len,
void *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
((void) md_alg);
ret = mbedtls_ecdsa_read_signature_restartable(
@@ -644,6 +767,8 @@ static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
#endif /* SIZE_MAX > UINT_MAX */
*sig_len = rsa_alt->key_len_func( rsa_alt->key );
+ if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
md_alg, (unsigned int) hash_len, hash, sig ) );
@@ -672,7 +797,7 @@ static int rsa_alt_check_pair( const void *pub, const void *prv )
unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
unsigned char hash[32];
size_t sig_len = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
@@ -741,4 +866,204 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+static void *pk_opaque_alloc_wrap( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( psa_key_id_t ) );
+
+ /* no _init() function to call, an calloc() already zeroized */
+
+ return( ctx );
+}
+
+static void pk_opaque_free_wrap( void *ctx )
+{
+ mbedtls_platform_zeroize( ctx, sizeof( psa_key_id_t ) );
+ mbedtls_free( ctx );
+}
+
+static size_t pk_opaque_get_bitlen( const void *ctx )
+{
+ const psa_key_id_t *key = (const psa_key_id_t *) ctx;
+ size_t bits;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ if( PSA_SUCCESS != psa_get_key_attributes( *key, &attributes ) )
+ return( 0 );
+
+ bits = psa_get_key_bits( &attributes );
+ psa_reset_key_attributes( &attributes );
+ return( bits );
+}
+
+static int pk_opaque_can_do( mbedtls_pk_type_t type )
+{
+ /* For now opaque PSA keys can only wrap ECC keypairs,
+ * as checked by setup_psa().
+ * Also, ECKEY_DH does not really make sense with the current API. */
+ return( type == MBEDTLS_PK_ECKEY ||
+ type == MBEDTLS_PK_ECDSA );
+}
+
+#if defined(MBEDTLS_ECDSA_C)
+
+/*
+ * Simultaneously convert and move raw MPI from the beginning of a buffer
+ * to an ASN.1 MPI at the end of the buffer.
+ * See also mbedtls_asn1_write_mpi().
+ *
+ * p: pointer to the end of the output buffer
+ * start: start of the output buffer, and also of the mpi to write at the end
+ * n_len: length of the mpi to read from start
+ */
+static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,
+ size_t n_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0;
+
+ if( (size_t)( *p - start ) < n_len )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+ len = n_len;
+ *p -= len;
+ memmove( *p, start, len );
+
+ /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
+ * Neither r nor s should be 0, but as a failsafe measure, still detect
+ * that rather than overflowing the buffer in case of a PSA error. */
+ while( len > 0 && **p == 0x00 )
+ {
+ ++(*p);
+ --len;
+ }
+
+ /* this is only reached if the signature was invalid */
+ if( len == 0 )
+ return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+
+ /* if the msb is 1, ASN.1 requires that we prepend a 0.
+ * Neither r nor s can be 0, so we can assume len > 0 at all times. */
+ if( **p & 0x80 )
+ {
+ if( *p - start < 1 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+ *--(*p) = 0x00;
+ len += 1;
+ }
+
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
+ MBEDTLS_ASN1_INTEGER ) );
+
+ return( (int) len );
+}
+
+/* Transcode signature from PSA format to ASN.1 sequence.
+ * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
+ * MPIs, and in-place.
+ *
+ * [in/out] sig: the signature pre- and post-transcoding
+ * [in/out] sig_len: signature length pre- and post-transcoding
+ * [int] buf_len: the available size the in/out buffer
+ */
+static int pk_ecdsa_sig_asn1_from_psa( unsigned char *sig, size_t *sig_len,
+ size_t buf_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0;
+ const size_t rs_len = *sig_len / 2;
+ unsigned char *p = sig + buf_len;
+
+ MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) );
+ MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) );
+
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
+
+ memmove( sig, p, len );
+ *sig_len = len;
+
+ return( 0 );
+}
+
+#endif /* MBEDTLS_ECDSA_C */
+
+static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ unsigned char *sig, size_t *sig_len,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+#if !defined(MBEDTLS_ECDSA_C)
+ ((void) ctx);
+ ((void) md_alg);
+ ((void) hash);
+ ((void) hash_len);
+ ((void) sig);
+ ((void) sig_len);
+ ((void) f_rng);
+ ((void) p_rng);
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+#else /* !MBEDTLS_ECDSA_C */
+ const psa_key_id_t *key = (const psa_key_id_t *) ctx;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
+ size_t buf_len;
+ psa_status_t status;
+
+ /* PSA has its own RNG */
+ (void) f_rng;
+ (void) p_rng;
+
+ /* PSA needs an output buffer of known size, but our API doesn't provide
+ * that information. Assume that the buffer is large enough for a
+ * maximal-length signature with that key (otherwise the application is
+ * buggy anyway). */
+ status = psa_get_key_attributes( *key, &attributes );
+ if( status != PSA_SUCCESS )
+ return( mbedtls_psa_err_translate_pk( status ) );
+ buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( psa_get_key_bits( &attributes ) );
+ psa_reset_key_attributes( &attributes );
+ if( buf_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ /* make the signature */
+ status = psa_sign_hash( *key, alg, hash, hash_len,
+ sig, buf_len, sig_len );
+ if( status != PSA_SUCCESS )
+ return( mbedtls_psa_err_translate_pk( status ) );
+
+ /* transcode it to ASN.1 sequence */
+ return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) );
+#endif /* !MBEDTLS_ECDSA_C */
+}
+
+const mbedtls_pk_info_t mbedtls_pk_opaque_info = {
+ MBEDTLS_PK_OPAQUE,
+ "Opaque",
+ pk_opaque_get_bitlen,
+ pk_opaque_can_do,
+ NULL, /* verify - will be done later */
+ pk_opaque_sign_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+ NULL, /* restartable verify - not relevant */
+ NULL, /* restartable sign - not relevant */
+#endif
+ NULL, /* decrypt - will be done later */
+ NULL, /* encrypt - will be done later */
+ NULL, /* check_pair - could be done later or left NULL */
+ pk_opaque_alloc_wrap,
+ pk_opaque_free_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+ NULL, /* restart alloc - not relevant */
+ NULL, /* restart free - not relevant */
+#endif
+ NULL, /* debug - could be done later, or even left NULL */
+};
+
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#endif /* MBEDTLS_PK_C */
diff --git a/thirdparty/mbedtls/library/pkcs11.c b/thirdparty/mbedtls/library/pkcs11.c
index cf484b86eb..4deccf3f60 100644
--- a/thirdparty/mbedtls/library/pkcs11.c
+++ b/thirdparty/mbedtls/library/pkcs11.c
@@ -6,13 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,27 +19,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#include "mbedtls/pkcs11.h"
diff --git a/thirdparty/mbedtls/library/pkcs12.c b/thirdparty/mbedtls/library/pkcs12.c
index 05ade49e93..cacf7dba22 100644
--- a/thirdparty/mbedtls/library/pkcs12.c
+++ b/thirdparty/mbedtls/library/pkcs12.c
@@ -2,13 +2,7 @@
* PKCS#12 Personal Information Exchange Syntax
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The PKCS #12 Personal Information Exchange Syntax Standard v1.1
@@ -50,11 +23,7 @@
* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PKCS12_C)
@@ -62,6 +31,7 @@
#include "mbedtls/asn1.h"
#include "mbedtls/cipher.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -78,7 +48,7 @@
static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
mbedtls_asn1_buf *salt, int *iterations )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char **p = &params->p;
const unsigned char *end = params->p + params->len;
@@ -90,21 +60,21 @@ static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
*
*/
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret ) );
salt->p = *p;
*p += salt->len;
if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret ) );
if( *p != end )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -170,7 +140,7 @@ int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
((void) output);
return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
#else
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char key[16];
mbedtls_arc4_context ctx;
((void) mode);
@@ -289,7 +259,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
const unsigned char *salt, size_t saltlen,
mbedtls_md_type_t md_type, int id, int iterations )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned int j;
unsigned char diversifier[128];
@@ -400,8 +370,8 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
for( i = v; i > 0; i-- )
{
j = salt_block[i - 1] + hash_block[i - 1] + c;
- c = (unsigned char) (j >> 8);
- salt_block[i - 1] = j & 0xFF;
+ c = MBEDTLS_BYTE_1( j );
+ salt_block[i - 1] = MBEDTLS_BYTE_0( j );
}
}
@@ -412,8 +382,8 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
for( i = v; i > 0; i-- )
{
j = pwd_block[i - 1] + hash_block[i - 1] + c;
- c = (unsigned char) (j >> 8);
- pwd_block[i - 1] = j & 0xFF;
+ c = MBEDTLS_BYTE_1( j );
+ pwd_block[i - 1] = MBEDTLS_BYTE_0( j );
}
}
}
diff --git a/thirdparty/mbedtls/library/pkcs5.c b/thirdparty/mbedtls/library/pkcs5.c
index c4447f1546..2b014d91c8 100644
--- a/thirdparty/mbedtls/library/pkcs5.c
+++ b/thirdparty/mbedtls/library/pkcs5.c
@@ -6,13 +6,7 @@
* \author Mathias Olsson <mathias@kompetensum.com>
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,27 +19,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* PKCS#5 includes PBKDF2 and more
@@ -54,15 +27,12 @@
* http://tools.ietf.org/html/rfc6070 (Test vectors)
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PKCS5_C)
#include "mbedtls/pkcs5.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "mbedtls/asn1.h"
@@ -84,14 +54,14 @@ 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 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_asn1_buf prf_alg_oid;
unsigned char *p = params->p;
const unsigned char *end = params->p + params->len;
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
/*
* PBKDF2-params ::= SEQUENCE {
* salt OCTET STRING,
@@ -101,14 +71,15 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
* }
*
*/
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len,
+ MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
salt->p = p;
p += salt->len;
if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
if( p == end )
return( 0 );
@@ -116,21 +87,21 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 )
{
if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
}
if( p == end )
return( 0 );
if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 )
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
if( p != end )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -163,11 +134,12 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
* }
*/
if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
- if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid,
+ &kdf_alg_params ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
// Only PBKDF2 supported at the moment
//
@@ -188,7 +160,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
&enc_scheme_params ) ) != 0 )
{
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
}
if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
@@ -227,7 +199,8 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
goto exit;
- if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
+ if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen,
+ (mbedtls_operation_t) mode ) ) != 0 )
goto exit;
if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
@@ -242,12 +215,14 @@ exit:
}
#endif /* MBEDTLS_ASN1_PARSE_C */
-int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
+int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx,
+ const unsigned char *password,
size_t plen, const unsigned char *salt, size_t slen,
unsigned int iteration_count,
uint32_t key_length, unsigned char *output )
{
- int ret = 0, j;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ int j;
unsigned int i;
unsigned char md1[MBEDTLS_MD_MAX_SIZE];
unsigned char work[MBEDTLS_MD_MAX_SIZE];
@@ -264,13 +239,12 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
#endif
+ if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
+ return( ret );
while( key_length )
{
// U1 ends up in work
//
- if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
- goto cleanup;
-
if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
goto cleanup;
@@ -280,21 +254,24 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
goto cleanup;
+ if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 )
+ goto cleanup;
+
memcpy( md1, work, md_size );
for( i = 1; i < iteration_count; i++ )
{
// U2 ends up in md1
//
- if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
- goto cleanup;
-
if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
goto cleanup;
+ if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 )
+ goto cleanup;
+
// U1 xor U2
//
for( j = 0; j < md_size; j++ )
@@ -334,10 +311,10 @@ int mbedtls_pkcs5_self_test( int verbose )
#define MAX_TESTS 6
-static const size_t plen[MAX_TESTS] =
+static const size_t plen_test_data[MAX_TESTS] =
{ 8, 8, 8, 24, 9 };
-static const unsigned char password[MAX_TESTS][32] =
+static const unsigned char password_test_data[MAX_TESTS][32] =
{
"password",
"password",
@@ -346,10 +323,10 @@ static const unsigned char password[MAX_TESTS][32] =
"pass\0word",
};
-static const size_t slen[MAX_TESTS] =
+static const size_t slen_test_data[MAX_TESTS] =
{ 4, 4, 4, 36, 5 };
-static const unsigned char salt[MAX_TESTS][40] =
+static const unsigned char salt_test_data[MAX_TESTS][40] =
{
"salt",
"salt",
@@ -358,13 +335,13 @@ static const unsigned char salt[MAX_TESTS][40] =
"sa\0lt",
};
-static const uint32_t it_cnt[MAX_TESTS] =
+static const uint32_t it_cnt_test_data[MAX_TESTS] =
{ 1, 2, 4096, 4096, 4096 };
-static const uint32_t key_len[MAX_TESTS] =
+static const uint32_t key_len_test_data[MAX_TESTS] =
{ 20, 20, 20, 25, 16 };
-static const unsigned char result_key[MAX_TESTS][32] =
+static const unsigned char result_key_test_data[MAX_TESTS][32] =
{
{ 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
@@ -410,10 +387,12 @@ int mbedtls_pkcs5_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i );
- ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
- slen[i], it_cnt[i], key_len[i], key );
+ ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password_test_data[i],
+ plen_test_data[i], salt_test_data[i],
+ slen_test_data[i], it_cnt_test_data[i],
+ key_len_test_data[i], key );
if( ret != 0 ||
- memcmp( result_key[i], key, key_len[i] ) != 0 )
+ memcmp( result_key_test_data[i], key, key_len_test_data[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
diff --git a/thirdparty/mbedtls/library/pkparse.c b/thirdparty/mbedtls/library/pkparse.c
index 8471b51320..535ed70eb1 100644
--- a/thirdparty/mbedtls/library/pkparse.c
+++ b/thirdparty/mbedtls/library/pkparse.c
@@ -2,13 +2,7 @@
* Public Key layer for parsing key files and structures
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PK_PARSE_C)
@@ -56,6 +25,7 @@
#include "mbedtls/asn1.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -155,7 +125,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
const char *path, const char *pwd )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -182,7 +152,7 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
*/
int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -213,11 +183,11 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
mbedtls_asn1_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ( end - *p < 1 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
/* Tag may be either OID or SEQUENCE */
params->tag = **p;
@@ -227,21 +197,21 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
#endif
)
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
}
if( ( ret = mbedtls_asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
params->p = *p;
*p += params->len;
if( *p != end )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -268,7 +238,7 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
*/
static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = params->p;
const unsigned char * const end = params->p + params->len;
const unsigned char *end_field, *end_curve;
@@ -277,7 +247,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
/* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( ver < 1 || ver > 3 )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
@@ -315,13 +285,13 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
/* Prime-p ::= INTEGER -- Field of size p. */
if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
grp->pbits = mbedtls_mpi_bitlen( &grp->P );
if( p != end_field )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/*
* Curve ::= SEQUENCE {
@@ -345,7 +315,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
p += len;
@@ -353,7 +323,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
p += len;
@@ -363,14 +333,14 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
p += len;
if( p != end_curve )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/*
* ECPoint ::= OCTET STRING
*/
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G,
( const unsigned char *) p, len ) ) != 0 )
@@ -396,7 +366,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
* order INTEGER
*/
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
grp->nbits = mbedtls_mpi_bitlen( &grp->N );
@@ -458,7 +428,7 @@ cleanup:
static int pk_group_id_from_specified( const mbedtls_asn1_buf *params,
mbedtls_ecp_group_id *grp_id )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group grp;
mbedtls_ecp_group_init( &grp );
@@ -485,7 +455,7 @@ cleanup:
*/
static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group_id grp_id;
if( params->tag == MBEDTLS_ASN1_OID )
@@ -525,7 +495,7 @@ static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *g
static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
mbedtls_ecp_keypair *key )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q,
(const unsigned char *) *p, end - *p ) ) == 0 )
@@ -553,20 +523,20 @@ static int pk_get_rsapubkey( unsigned char **p,
const unsigned char *end,
mbedtls_rsa_context *rsa )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
if( *p + len != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/* Import N */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
NULL, 0, NULL, 0 ) ) != 0 )
@@ -576,7 +546,7 @@ static int pk_get_rsapubkey( unsigned char **p,
/* Import E */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, *p, len ) ) != 0 )
@@ -591,8 +561,8 @@ static int pk_get_rsapubkey( unsigned char **p,
}
if( *p != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -608,13 +578,13 @@ static int pk_get_pk_alg( unsigned char **p,
const unsigned char *end,
mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_asn1_buf alg_oid;
memset( params, 0, sizeof(mbedtls_asn1_buf) );
if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_ALG, ret ) );
if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
@@ -640,7 +610,7 @@ static int pk_get_pk_alg( unsigned char **p,
int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
mbedtls_pk_context *pk )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
mbedtls_asn1_buf alg_params;
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
@@ -654,7 +624,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = *p + len;
@@ -663,11 +633,11 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
return( ret );
if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
if( *p + len != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
@@ -692,8 +662,8 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
if( ret == 0 && *p != end )
- ret = MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
if( ret != 0 )
mbedtls_pk_free( pk );
@@ -764,14 +734,14 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
if( version != 0 )
@@ -861,8 +831,8 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
if( p != end )
{
- ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
}
cleanup:
@@ -873,7 +843,7 @@ cleanup:
{
/* Wrap error code if it's coming from a lower level */
if( ( ret & 0xff80 ) == 0 )
- ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret );
else
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
@@ -892,7 +862,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
const unsigned char *key,
size_t keylen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int version, pubkey_done;
size_t len;
mbedtls_asn1_buf params;
@@ -913,24 +883,24 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( version != 1 )
return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 )
{
mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
p += len;
@@ -954,7 +924,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
{
mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
}
@@ -970,11 +940,11 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
end2 = p + len;
if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( p + len != end2 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
pubkey_done = 1;
@@ -991,7 +961,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
{
mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
}
@@ -1000,7 +970,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
NULL, NULL ) ) != 0 )
{
mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
@@ -1058,26 +1028,28 @@ static int pk_parse_key_pkcs8_unencrypted_der(
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( version != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_VERSION, ret ) );
if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
+ {
return( ret );
+ }
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( len < 1 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
@@ -1160,16 +1132,16 @@ static int pk_parse_key_pkcs8_encrypted_der(
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = p + len;
if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
buf = p;
@@ -1245,7 +1217,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
const unsigned char *key, size_t keylen,
const unsigned char *pwd, size_t pwdlen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_pk_info_t *pk_info;
#if defined(MBEDTLS_PEM_PARSE_C)
size_t len;
@@ -1460,7 +1432,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
const unsigned char *key, size_t keylen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p;
#if defined(MBEDTLS_RSA_C)
const mbedtls_pk_info_t *pk_info;
@@ -1551,7 +1523,8 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
return( ret );
}
mbedtls_pk_free( ctx );
- if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
+ if( ret != ( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) )
{
return( ret );
}
diff --git a/thirdparty/mbedtls/library/pkwrite.c b/thirdparty/mbedtls/library/pkwrite.c
index a770dfb93e..566153dd93 100644
--- a/thirdparty/mbedtls/library/pkwrite.c
+++ b/thirdparty/mbedtls/library/pkwrite.c
@@ -2,13 +2,7 @@
* Public Key layer for writing key files and structures
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PK_WRITE_C)
@@ -56,6 +25,7 @@
#include "mbedtls/asn1write.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -74,6 +44,10 @@
#include "mbedtls/pem.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -98,7 +72,7 @@
static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
mbedtls_rsa_context *rsa )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_mpi T;
@@ -137,7 +111,7 @@ end_of_export:
static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
@@ -165,7 +139,7 @@ static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
static int pk_write_ec_param( unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
const char *oid;
size_t oid_len;
@@ -184,11 +158,11 @@ static int pk_write_ec_param( unsigned char **p, unsigned char *start,
static int pk_write_ec_private( unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t byte_length = ( ec->grp.pbits + 7 ) / 8;
unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
- ret = mbedtls_mpi_write_binary( &ec->d, tmp, byte_length );
+ ret = mbedtls_ecp_write_key( ec, tmp, byte_length );
if( ret != 0 )
goto exit;
ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length );
@@ -202,7 +176,7 @@ exit:
int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
const mbedtls_pk_context *key )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
PK_VALIDATE_RET( p != NULL );
@@ -220,6 +194,29 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) );
else
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_OPAQUE )
+ {
+ size_t buffer_size;
+ psa_key_id_t* key_id = (psa_key_id_t*) key->pk_ctx;
+
+ if ( *p < start )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ buffer_size = (size_t)( *p - start );
+ if ( psa_export_public_key( *key_id, start, buffer_size, &len )
+ != PSA_SUCCESS )
+ {
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+ }
+ else
+ {
+ *p -= len;
+ memmove( *p, start, len );
+ }
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
return( (int) len );
@@ -227,9 +224,10 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *c;
size_t len = 0, par_len = 0, oid_len;
+ mbedtls_pk_type_t pk_type;
const char *oid;
PK_VALIDATE_RET( key != NULL );
@@ -255,18 +253,52 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
- if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
- &oid, &oid_len ) ) != 0 )
- {
- return( ret );
- }
-
+ pk_type = mbedtls_pk_get_type( key );
#if defined(MBEDTLS_ECP_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
+ if( pk_type == MBEDTLS_PK_ECKEY )
{
MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
}
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( pk_type == MBEDTLS_PK_OPAQUE )
+ {
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t key_type;
+ psa_key_id_t key_id;
+ psa_ecc_family_t curve;
+ size_t bits;
+
+ key_id = *((psa_key_id_t*) key->pk_ctx );
+ if( PSA_SUCCESS != psa_get_key_attributes( key_id, &attributes ) )
+ return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+ key_type = psa_get_key_type( &attributes );
+ bits = psa_get_key_bits( &attributes );
+ psa_reset_key_attributes( &attributes );
+
+ curve = PSA_KEY_TYPE_ECC_GET_FAMILY( key_type );
+ if( curve == 0 )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+ ret = mbedtls_psa_get_ecc_oid_from_id( curve, bits, &oid, &oid_len );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+ /* Write EC algorithm parameters; that's akin
+ * to pk_write_ec_param() above. */
+ MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_oid( &c, buf,
+ oid, oid_len ) );
+
+ /* The rest of the function works as for legacy EC contexts. */
+ pk_type = MBEDTLS_PK_ECKEY;
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ if( ( ret = mbedtls_oid_get_oid_by_pk_alg( pk_type, &oid,
+ &oid_len ) ) != 0 )
+ {
+ return( ret );
+ }
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
par_len ) );
@@ -280,7 +312,7 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si
int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *c;
size_t len = 0;
@@ -523,7 +555,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char output_buf[PUB_DER_MAX_BYTES];
size_t olen = 0;
@@ -548,7 +580,7 @@ int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, si
int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char output_buf[PRV_DER_MAX_BYTES];
const char *begin, *end;
size_t olen = 0;
diff --git a/thirdparty/mbedtls/library/platform.c b/thirdparty/mbedtls/library/platform.c
index c4c3fd332d..e742fde7cc 100644
--- a/thirdparty/mbedtls/library/platform.c
+++ b/thirdparty/mbedtls/library/platform.c
@@ -2,13 +2,7 @@
* Platform abstraction layer
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,39 +15,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
/* The compile time configuration of memory allocation via the macros
* MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime
@@ -107,28 +77,15 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
!( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&
defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */
-#if defined(_WIN32)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
#include <stdarg.h>
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
va_list argp;
- /* Avoid calling the invalid parameter handler by checking ourselves */
- if( s == NULL || n == 0 || fmt == NULL )
- return( -1 );
-
va_start( argp, fmt );
-#if defined(_TRUNCATE) && !defined(__MINGW32__)
- ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
-#else
- ret = _vsnprintf( s, n, fmt, argp );
- if( ret < 0 || (size_t) ret == n )
- {
- s[n-1] = '\0';
- ret = -1;
- }
-#endif
+ ret = mbedtls_vsnprintf( s, n, fmt, argp );
va_end( argp );
return( ret );
@@ -165,6 +122,62 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
}
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#include <stdarg.h>
+int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* Avoid calling the invalid parameter handler by checking ourselves */
+ if( s == NULL || n == 0 || fmt == NULL )
+ return( -1 );
+
+#if defined(_TRUNCATE)
+ ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg );
+#else
+ ret = vsnprintf( s, n, fmt, arg );
+ if( ret < 0 || (size_t) ret == n )
+ {
+ s[n-1] = '\0';
+ ret = -1;
+ }
+#endif
+
+ return( ret );
+}
+#endif
+
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_vsnprintf_uninit( char * s, size_t n,
+ const char * format, va_list arg )
+{
+ ((void) s);
+ ((void) n);
+ ((void) format);
+ ((void) arg);
+ return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */
+
+int (*mbedtls_vsnprintf)( char * s, size_t n,
+ const char * format,
+ va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF;
+
+int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
+ const char * format,
+ va_list arg ) )
+{
+ mbedtls_vsnprintf = vsnprintf_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
/*
diff --git a/thirdparty/mbedtls/library/platform_util.c b/thirdparty/mbedtls/library/platform_util.c
index c8cd52d52a..98fe5deb2d 100644
--- a/thirdparty/mbedtls/library/platform_util.c
+++ b/thirdparty/mbedtls/library/platform_util.c
@@ -3,13 +3,7 @@
* library.
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -22,27 +16,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -53,11 +26,7 @@
#define _POSIX_C_SOURCE 200112L
#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/platform.h"
diff --git a/thirdparty/mbedtls/library/poly1305.c b/thirdparty/mbedtls/library/poly1305.c
index 5b023f04e4..7375a0c572 100644
--- a/thirdparty/mbedtls/library/poly1305.c
+++ b/thirdparty/mbedtls/library/poly1305.c
@@ -4,13 +4,7 @@
* \brief Poly1305 authentication algorithm.
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,38 +17,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_POLY1305_C)
#include "mbedtls/poly1305.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -82,13 +52,6 @@
#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
-#define BYTES_TO_U32_LE( data, offset ) \
- ( (uint32_t) (data)[offset] \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
- )
-
/*
* Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
* However we provided an alternative for platforms without such a multiplier.
@@ -159,10 +122,10 @@ static void poly1305_process( mbedtls_poly1305_context *ctx,
for( i = 0U; i < nblocks; i++ )
{
/* The input block is treated as a 128-bit little-endian integer */
- d0 = BYTES_TO_U32_LE( input, offset + 0 );
- d1 = BYTES_TO_U32_LE( input, offset + 4 );
- d2 = BYTES_TO_U32_LE( input, offset + 8 );
- d3 = BYTES_TO_U32_LE( input, offset + 12 );
+ d0 = MBEDTLS_GET_UINT32_LE( input, offset + 0 );
+ d1 = MBEDTLS_GET_UINT32_LE( input, offset + 4 );
+ d2 = MBEDTLS_GET_UINT32_LE( input, offset + 8 );
+ d3 = MBEDTLS_GET_UINT32_LE( input, offset + 12 );
/* Compute: acc += (padded) block as a 130-bit integer */
d0 += (uint64_t) acc0;
@@ -287,22 +250,10 @@ static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
/* Compute MAC (128 least significant bits of the accumulator) */
- mac[ 0] = (unsigned char)( acc0 );
- mac[ 1] = (unsigned char)( acc0 >> 8 );
- mac[ 2] = (unsigned char)( acc0 >> 16 );
- mac[ 3] = (unsigned char)( acc0 >> 24 );
- mac[ 4] = (unsigned char)( acc1 );
- mac[ 5] = (unsigned char)( acc1 >> 8 );
- mac[ 6] = (unsigned char)( acc1 >> 16 );
- mac[ 7] = (unsigned char)( acc1 >> 24 );
- mac[ 8] = (unsigned char)( acc2 );
- mac[ 9] = (unsigned char)( acc2 >> 8 );
- mac[10] = (unsigned char)( acc2 >> 16 );
- mac[11] = (unsigned char)( acc2 >> 24 );
- mac[12] = (unsigned char)( acc3 );
- mac[13] = (unsigned char)( acc3 >> 8 );
- mac[14] = (unsigned char)( acc3 >> 16 );
- mac[15] = (unsigned char)( acc3 >> 24 );
+ MBEDTLS_PUT_UINT32_LE( acc0, mac, 0 );
+ MBEDTLS_PUT_UINT32_LE( acc1, mac, 4 );
+ MBEDTLS_PUT_UINT32_LE( acc2, mac, 8 );
+ MBEDTLS_PUT_UINT32_LE( acc3, mac, 12 );
}
void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
@@ -327,15 +278,15 @@ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
POLY1305_VALIDATE_RET( key != NULL );
/* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
- ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
- ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
- ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
- ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
+ ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 ) & 0x0FFFFFFFU;
+ ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 ) & 0x0FFFFFFCU;
+ ctx->r[2] = MBEDTLS_GET_UINT32_LE( key, 8 ) & 0x0FFFFFFCU;
+ ctx->r[3] = MBEDTLS_GET_UINT32_LE( key, 12 ) & 0x0FFFFFFCU;
- ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
- ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
- ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
- ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
+ ctx->s[0] = MBEDTLS_GET_UINT32_LE( key, 16 );
+ ctx->s[1] = MBEDTLS_GET_UINT32_LE( key, 20 );
+ ctx->s[2] = MBEDTLS_GET_UINT32_LE( key, 24 );
+ ctx->s[3] = MBEDTLS_GET_UINT32_LE( key, 28 );
/* Initial accumulator state */
ctx->acc[0] = 0U;
@@ -448,7 +399,7 @@ int mbedtls_poly1305_mac( const unsigned char key[32],
unsigned char mac[16] )
{
mbedtls_poly1305_context ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
POLY1305_VALIDATE_RET( key != NULL );
POLY1305_VALIDATE_RET( mac != NULL );
POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
@@ -537,6 +488,9 @@ static const unsigned char test_mac[2][16] =
}
};
+/* Make sure no other definition is already present. */
+#undef ASSERT
+
#define ASSERT( cond, args ) \
do \
{ \
@@ -554,7 +508,7 @@ int mbedtls_poly1305_self_test( int verbose )
{
unsigned char mac[16];
unsigned i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
for( i = 0U; i < 2U; i++ )
{
diff --git a/thirdparty/mbedtls/library/ripemd160.c b/thirdparty/mbedtls/library/ripemd160.c
index c090c8f9d2..aed7322cff 100644
--- a/thirdparty/mbedtls/library/ripemd160.c
+++ b/thirdparty/mbedtls/library/ripemd160.c
@@ -2,13 +2,7 @@
* RIPE MD-160 implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -50,16 +23,13 @@
* http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_RIPEMD160_C)
#include "mbedtls/ripemd160.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -74,29 +44,6 @@
#if !defined(MBEDTLS_RIPEMD160_ALT)
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
@@ -152,22 +99,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
} local;
- GET_UINT32_LE( local.X[ 0], data, 0 );
- GET_UINT32_LE( local.X[ 1], data, 4 );
- GET_UINT32_LE( local.X[ 2], data, 8 );
- GET_UINT32_LE( local.X[ 3], data, 12 );
- GET_UINT32_LE( local.X[ 4], data, 16 );
- GET_UINT32_LE( local.X[ 5], data, 20 );
- GET_UINT32_LE( local.X[ 6], data, 24 );
- GET_UINT32_LE( local.X[ 7], data, 28 );
- GET_UINT32_LE( local.X[ 8], data, 32 );
- GET_UINT32_LE( local.X[ 9], data, 36 );
- GET_UINT32_LE( local.X[10], data, 40 );
- GET_UINT32_LE( local.X[11], data, 44 );
- GET_UINT32_LE( local.X[12], data, 48 );
- GET_UINT32_LE( local.X[13], data, 52 );
- GET_UINT32_LE( local.X[14], data, 56 );
- GET_UINT32_LE( local.X[15], data, 60 );
+ local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
+ local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
+ local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
+ local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+ local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+ local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+ local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+ local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+ local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+ local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+ local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+ local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+ local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+ local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+ local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+ local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
local.A = local.Ap = ctx->state[0];
local.B = local.Bp = ctx->state[1];
@@ -353,7 +300,7 @@ int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -421,7 +368,7 @@ static const unsigned char ripemd160_padding[64] =
int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
unsigned char output[20] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
@@ -430,8 +377,8 @@ int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, msglen, 0 );
- PUT_UINT32_LE( high, msglen, 4 );
+ MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
+ MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
@@ -444,11 +391,11 @@ int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
if( ret != 0 )
return( ret );
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
- PUT_UINT32_LE( ctx->state[4], output, 16 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[4], output, 16 );
return( 0 );
}
@@ -470,7 +417,7 @@ int mbedtls_ripemd160_ret( const unsigned char *input,
size_t ilen,
unsigned char output[20] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ripemd160_context ctx;
mbedtls_ripemd160_init( &ctx );
diff --git a/thirdparty/mbedtls/library/rsa.c b/thirdparty/mbedtls/library/rsa.c
index 47d784c1ba..8a5d40ff1e 100644
--- a/thirdparty/mbedtls/library/rsa.c
+++ b/thirdparty/mbedtls/library/rsa.c
@@ -2,13 +2,7 @@
* The RSA public-key cryptosystem
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -62,11 +35,7 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_RSA_C)
@@ -74,6 +43,9 @@
#include "mbedtls/rsa_internal.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
@@ -102,28 +74,12 @@
#define RSA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#if defined(MBEDTLS_PKCS1_V15)
-/* constant-time buffer comparison */
-static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
-{
- size_t i;
- const unsigned char *A = (const unsigned char *) a;
- const unsigned char *B = (const unsigned char *) b;
- unsigned char diff = 0;
-
- for( i = 0; i < n; i++ )
- diff |= A[i] ^ B[i];
-
- return( diff );
-}
-#endif /* MBEDTLS_PKCS1_V15 */
-
int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
const mbedtls_mpi *N,
const mbedtls_mpi *P, const mbedtls_mpi *Q,
const mbedtls_mpi *D, const mbedtls_mpi *E )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
RSA_VALIDATE_RET( ctx != NULL );
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
@@ -132,7 +88,7 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
if( N != NULL )
@@ -172,7 +128,7 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
cleanup:
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
return( 0 );
}
@@ -323,7 +279,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
&ctx->Q ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
ctx->len = mbedtls_mpi_size( &ctx->N );
@@ -338,7 +294,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
&ctx->P, &ctx->Q );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
else if( d_missing )
@@ -348,7 +304,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
&ctx->E,
&ctx->D ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
}
@@ -363,7 +319,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
&ctx->DP, &ctx->DQ, &ctx->QP );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#endif /* MBEDTLS_RSA_NO_CRT */
@@ -426,7 +382,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
mbedtls_mpi *D, mbedtls_mpi *E )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
@@ -470,7 +426,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
@@ -491,13 +447,13 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#else
if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
DP, DQ, QP ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#endif
@@ -564,7 +520,7 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
void *p_rng,
unsigned int nbits, int exponent )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi H, G, L;
int prime_quality = 0;
RSA_VALIDATE_RET( ctx != NULL );
@@ -665,8 +621,9 @@ cleanup:
if( ret != 0 )
{
mbedtls_rsa_free( ctx );
+
if( ( -ret & ~0x7f ) == 0 )
- ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret );
return( ret );
}
@@ -761,7 +718,7 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen;
mbedtls_mpi T;
RSA_VALIDATE_RET( ctx != NULL );
@@ -799,7 +756,7 @@ cleanup:
mbedtls_mpi_free( &T );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret ) );
return( 0 );
}
@@ -899,7 +856,7 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen;
/* Temporary holding the result */
@@ -1115,7 +1072,7 @@ cleanup:
mbedtls_mpi_free( &I );
if( ret != 0 && ret >= -0x007f )
- return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret ) );
return( ret );
}
@@ -1192,7 +1149,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
unsigned char *output )
{
size_t olen;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = output;
unsigned int hlen;
const mbedtls_md_info_t *md_info;
@@ -1202,7 +1159,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
@@ -1228,7 +1185,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
/* Generate a random octet string seed */
if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
p += hlen;
@@ -1238,7 +1195,8 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
p += hlen;
p += olen - 2 * hlen - 2 - ilen;
*p++ = 1;
- memcpy( p, input, ilen );
+ if( ilen != 0 )
+ memcpy( p, input, ilen );
mbedtls_md_init( &md_ctx );
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
@@ -1278,14 +1236,14 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
unsigned char *output )
{
size_t nb_pad, olen;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = output;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1316,7 +1274,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
/* Check if RNG failed to generate data */
if( rng_dl == 0 || ret != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
p++;
}
@@ -1330,7 +1288,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
}
*p++ = 0;
- memcpy( p, input, ilen );
+ if( ilen != 0 )
+ memcpy( p, input, ilen );
return( ( mode == MBEDTLS_RSA_PUBLIC )
? mbedtls_rsa_public( ctx, output, output )
@@ -1352,7 +1311,7 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
switch( ctx->padding )
{
@@ -1387,7 +1346,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
unsigned char *output,
size_t output_max_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t ilen, i, pad_len;
unsigned char *p, bad, pad_done;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
@@ -1508,7 +1467,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
}
*olen = ilen - (p - buf);
- memcpy( output, p, *olen );
+ if( *olen != 0 )
+ memcpy( output, p, *olen );
ret = 0;
cleanup:
@@ -1520,126 +1480,21 @@ 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
*/
int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
- int mode, size_t *olen,
+ int mode,
+ size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len )
{
- int ret;
- size_t ilen, i, plaintext_max_size;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t ilen;
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;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
@@ -1649,9 +1504,6 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( olen != NULL );
ilen = ctx->len;
- plaintext_max_size = ( output_max_len > ilen - 11 ?
- ilen - 11 :
- output_max_len );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1666,109 +1518,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
if( ret != 0 )
goto cleanup;
- /* Check and get padding length in constant time and constant
- * memory trace. The first byte must be 0. */
- bad |= buf[0];
-
- if( mode == MBEDTLS_RSA_PRIVATE )
- {
- /* 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;
-
- /* 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 |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
- pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
- }
- }
- else
- {
- /* 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;
-
- /* 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 |= if_int( buf[i], 0, 1 );
- pad_count += if_int( pad_done, 0, 1 );
- bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
- }
- }
-
- /* 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;
+ ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding( mode, buf, ilen,
+ output, output_max_len, olen );
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -1816,23 +1567,21 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
}
#if defined(MBEDTLS_PKCS1_V21)
-/*
- * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
- */
-int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+static int rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
mbedtls_md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
+ int saltlen,
unsigned char *sig )
{
size_t olen;
unsigned char *p = sig;
- unsigned char salt[MBEDTLS_MD_MAX_SIZE];
+ unsigned char *salt = NULL;
size_t slen, min_slen, hlen, offset = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t msb;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
@@ -1868,31 +1617,44 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
hlen = mbedtls_md_get_size( md_info );
- /* Calculate the largest possible salt length. Normally this is the hash
- * length, which is the maximum length the salt can have. If there is not
- * enough room, use the maximum salt length that fits. The constraint is
- * that the hash length plus the salt length plus 2 bytes must be at most
- * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
- * (PKCS#1 v2.2) §9.1.1 step 3. */
- min_slen = hlen - 2;
- if( olen < hlen + min_slen + 2 )
+ if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY)
+ {
+ /* Calculate the largest possible salt length, up to the hash size.
+ * Normally this is the hash length, which is the maximum salt length
+ * according to FIPS 185-4 §5.5 (e) and common practice. If there is not
+ * enough room, use the maximum salt length that fits. The constraint is
+ * that the hash length plus the salt length plus 2 bytes must be at most
+ * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
+ * (PKCS#1 v2.2) §9.1.1 step 3. */
+ min_slen = hlen - 2;
+ if( olen < hlen + min_slen + 2 )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ else if( olen >= hlen + hlen + 2 )
+ slen = hlen;
+ else
+ slen = olen - hlen - 2;
+ }
+ else if ( (saltlen < 0) || (saltlen + hlen + 2 > olen) )
+ {
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- else if( olen >= hlen + hlen + 2 )
- slen = hlen;
+ }
else
- slen = olen - hlen - 2;
+ {
+ slen = (size_t) saltlen;
+ }
memset( sig, 0, olen );
- /* Generate salt of length slen */
- if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
-
/* Note: EMSA-PSS encoding is over the length of N - 1 bits */
msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
p += olen - hlen - slen - 2;
*p++ = 0x01;
- memcpy( p, salt, slen );
+
+ /* Generate salt of length slen in place in the encoded message */
+ salt = p;
+ if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
+
p += slen;
mbedtls_md_init( &md_ctx );
@@ -1926,8 +1688,6 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
p += hlen;
*p++ = 0xBC;
- mbedtls_platform_zeroize( salt, sizeof( salt ) );
-
exit:
mbedtls_md_free( &md_ctx );
@@ -1938,6 +1698,40 @@ exit:
? mbedtls_rsa_public( ctx, sig, sig )
: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
}
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with
+ * the option to pass in the salt length.
+ */
+int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ int saltlen,
+ unsigned char *sig )
+{
+ return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, md_alg,
+ hashlen, hash, saltlen, sig );
+}
+
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
+ */
+int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
+ hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig );
+}
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PKCS1_V15)
@@ -2087,7 +1881,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
const unsigned char *hash,
unsigned char *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *sig_try = NULL, *verif = NULL;
RSA_VALIDATE_RET( ctx != NULL );
@@ -2139,7 +1933,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
- if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
+ if( mbedtls_ct_memcmp( verif, sig, ctx->len ) != 0 )
{
ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
goto cleanup;
@@ -2213,7 +2007,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
int expected_salt_len,
const unsigned char *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t siglen;
unsigned char *p;
unsigned char *hash_start;
@@ -2441,8 +2235,8 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
* Compare
*/
- if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
- sig_len ) ) != 0 )
+ if( ( ret = mbedtls_ct_memcmp( encoded, encoded_expected,
+ sig_len ) ) != 0 )
{
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
goto cleanup;
@@ -2510,7 +2304,7 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
*/
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
RSA_VALIDATE_RET( dst != NULL );
RSA_VALIDATE_RET( src != NULL );
diff --git a/thirdparty/mbedtls/library/rsa_internal.c b/thirdparty/mbedtls/library/rsa_internal.c
index 4d94ca685a..d6ba97a14b 100644
--- a/thirdparty/mbedtls/library/rsa_internal.c
+++ b/thirdparty/mbedtls/library/rsa_internal.c
@@ -2,13 +2,7 @@
* Helper functions for the RSA module
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -22,34 +16,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- *
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_RSA_C)
diff --git a/thirdparty/mbedtls/library/sha1.c b/thirdparty/mbedtls/library/sha1.c
index e99a5e8635..0a5edafaff 100644
--- a/thirdparty/mbedtls/library/sha1.c
+++ b/thirdparty/mbedtls/library/sha1.c
@@ -2,13 +2,7 @@
* FIPS-180-1 compliant SHA-1 implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The SHA-1 standard was published by NIST in 1993.
@@ -49,16 +22,13 @@
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -78,29 +48,6 @@
#if !defined(MBEDTLS_SHA1_ALT)
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
{
SHA1_VALIDATE( ctx != NULL );
@@ -163,22 +110,22 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
SHA1_VALIDATE_RET( ctx != NULL );
SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
- GET_UINT32_BE( local.W[ 0], data, 0 );
- GET_UINT32_BE( local.W[ 1], data, 4 );
- GET_UINT32_BE( local.W[ 2], data, 8 );
- GET_UINT32_BE( local.W[ 3], data, 12 );
- GET_UINT32_BE( local.W[ 4], data, 16 );
- GET_UINT32_BE( local.W[ 5], data, 20 );
- GET_UINT32_BE( local.W[ 6], data, 24 );
- GET_UINT32_BE( local.W[ 7], data, 28 );
- GET_UINT32_BE( local.W[ 8], data, 32 );
- GET_UINT32_BE( local.W[ 9], data, 36 );
- GET_UINT32_BE( local.W[10], data, 40 );
- GET_UINT32_BE( local.W[11], data, 44 );
- GET_UINT32_BE( local.W[12], data, 48 );
- GET_UINT32_BE( local.W[13], data, 52 );
- GET_UINT32_BE( local.W[14], data, 56 );
- GET_UINT32_BE( local.W[15], data, 60 );
+ local.W[ 0] = MBEDTLS_GET_UINT32_BE( data, 0 );
+ local.W[ 1] = MBEDTLS_GET_UINT32_BE( data, 4 );
+ local.W[ 2] = MBEDTLS_GET_UINT32_BE( data, 8 );
+ local.W[ 3] = MBEDTLS_GET_UINT32_BE( data, 12 );
+ local.W[ 4] = MBEDTLS_GET_UINT32_BE( data, 16 );
+ local.W[ 5] = MBEDTLS_GET_UINT32_BE( data, 20 );
+ local.W[ 6] = MBEDTLS_GET_UINT32_BE( data, 24 );
+ local.W[ 7] = MBEDTLS_GET_UINT32_BE( data, 28 );
+ local.W[ 8] = MBEDTLS_GET_UINT32_BE( data, 32 );
+ local.W[ 9] = MBEDTLS_GET_UINT32_BE( data, 36 );
+ local.W[10] = MBEDTLS_GET_UINT32_BE( data, 40 );
+ local.W[11] = MBEDTLS_GET_UINT32_BE( data, 44 );
+ local.W[12] = MBEDTLS_GET_UINT32_BE( data, 48 );
+ local.W[13] = MBEDTLS_GET_UINT32_BE( data, 52 );
+ local.W[14] = MBEDTLS_GET_UINT32_BE( data, 56 );
+ local.W[15] = MBEDTLS_GET_UINT32_BE( data, 60 );
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
@@ -340,7 +287,7 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -401,7 +348,7 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
unsigned char output[20] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t used;
uint32_t high, low;
@@ -438,8 +385,8 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_BE( high, ctx->buffer, 56 );
- PUT_UINT32_BE( low, ctx->buffer, 60 );
+ MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
+ MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@@ -447,11 +394,11 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
/*
* Output final state
*/
- PUT_UINT32_BE( ctx->state[0], output, 0 );
- PUT_UINT32_BE( ctx->state[1], output, 4 );
- PUT_UINT32_BE( ctx->state[2], output, 8 );
- PUT_UINT32_BE( ctx->state[3], output, 12 );
- PUT_UINT32_BE( ctx->state[4], output, 16 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
return( 0 );
}
@@ -473,7 +420,7 @@ int mbedtls_sha1_ret( const unsigned char *input,
size_t ilen,
unsigned char output[20] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha1_context ctx;
SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
diff --git a/thirdparty/mbedtls/library/sha256.c b/thirdparty/mbedtls/library/sha256.c
index 75a8f8a2b2..db675efd1b 100644
--- a/thirdparty/mbedtls/library/sha256.c
+++ b/thirdparty/mbedtls/library/sha256.c
@@ -2,13 +2,7 @@
* FIPS-180-2 compliant SHA-256 implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
@@ -49,16 +22,13 @@
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -80,29 +50,6 @@
#if !defined(MBEDTLS_SHA256_ALT)
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-do { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-} while( 0 )
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-do { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-} while( 0 )
-#endif
-
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
{
SHA256_VALIDATE( ctx != NULL );
@@ -244,7 +191,7 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
for( i = 0; i < 64; i++ )
{
if( i < 16 )
- GET_UINT32_BE( local.W[i], data, 4 * i );
+ local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
else
R( i );
@@ -259,7 +206,7 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
}
#else /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 16; i++ )
- GET_UINT32_BE( local.W[i], data, 4 * i );
+ local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
for( i = 0; i < 16; i += 8 )
{
@@ -327,7 +274,7 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -388,7 +335,7 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
unsigned char output[32] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t used;
uint32_t high, low;
@@ -425,8 +372,8 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_BE( high, ctx->buffer, 56 );
- PUT_UINT32_BE( low, ctx->buffer, 60 );
+ MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
+ MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@@ -434,16 +381,16 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
/*
* Output final state
*/
- PUT_UINT32_BE( ctx->state[0], output, 0 );
- PUT_UINT32_BE( ctx->state[1], output, 4 );
- PUT_UINT32_BE( ctx->state[2], output, 8 );
- PUT_UINT32_BE( ctx->state[3], output, 12 );
- PUT_UINT32_BE( ctx->state[4], output, 16 );
- PUT_UINT32_BE( ctx->state[5], output, 20 );
- PUT_UINT32_BE( ctx->state[6], output, 24 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
if( ctx->is224 == 0 )
- PUT_UINT32_BE( ctx->state[7], output, 28 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
return( 0 );
}
@@ -466,7 +413,7 @@ int mbedtls_sha256_ret( const unsigned char *input,
unsigned char output[32],
int is224 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha256_context ctx;
SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
diff --git a/thirdparty/mbedtls/library/sha512.c b/thirdparty/mbedtls/library/sha512.c
index 3347afe5ff..02a135ca92 100644
--- a/thirdparty/mbedtls/library/sha512.c
+++ b/thirdparty/mbedtls/library/sha512.c
@@ -2,13 +2,7 @@
* FIPS-180-2 compliant SHA-384/512 implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
@@ -49,16 +22,13 @@
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SHA512_C)
#include "mbedtls/sha512.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#if defined(_MSC_VER) || defined(__WATCOMC__)
#define UL64(x) x##ui64
@@ -86,36 +56,14 @@
#if !defined(MBEDTLS_SHA512_ALT)
-/*
- * 64-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT64_BE
-#define GET_UINT64_BE(n,b,i) \
-{ \
- (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
- | ( (uint64_t) (b)[(i) + 1] << 48 ) \
- | ( (uint64_t) (b)[(i) + 2] << 40 ) \
- | ( (uint64_t) (b)[(i) + 3] << 32 ) \
- | ( (uint64_t) (b)[(i) + 4] << 24 ) \
- | ( (uint64_t) (b)[(i) + 5] << 16 ) \
- | ( (uint64_t) (b)[(i) + 6] << 8 ) \
- | ( (uint64_t) (b)[(i) + 7] ); \
-}
-#endif /* GET_UINT64_BE */
-
-#ifndef PUT_UINT64_BE
-#define PUT_UINT64_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
- (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 7] = (unsigned char) ( (n) ); \
+#if defined(MBEDTLS_SHA512_SMALLER)
+static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
+{
+ MBEDTLS_PUT_UINT64_BE(n, b, i);
}
-#endif /* PUT_UINT64_BE */
+#else
+#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
+#endif /* MBEDTLS_SHA512_SMALLER */
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
{
@@ -147,7 +95,11 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
{
SHA512_VALIDATE_RET( ctx != NULL );
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+#else
+ SHA512_VALIDATE_RET( is384 == 0 );
+#endif
ctx->total[0] = 0;
ctx->total[1] = 0;
@@ -166,6 +118,9 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
}
else
{
+#if defined(MBEDTLS_SHA512_NO_SHA384)
+ return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
+#else
/* SHA-384 */
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
ctx->state[1] = UL64(0x629A292A367CD507);
@@ -175,9 +130,12 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
ctx->state[5] = UL64(0x8EB44A8768581511);
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
+#endif /* MBEDTLS_SHA512_NO_SHA384 */
}
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
ctx->is384 = is384;
+#endif
return( 0 );
}
@@ -246,7 +204,7 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
struct
{
uint64_t temp1, temp2, W[80];
- uint64_t A, B, C, D, E, F, G, H;
+ uint64_t A[8];
} local;
SHA512_VALIDATE_RET( ctx != NULL );
@@ -272,56 +230,68 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
(d) += local.temp1; (h) = local.temp1 + local.temp2; \
} while( 0 )
+ for( i = 0; i < 8; i++ )
+ local.A[i] = ctx->state[i];
+
+#if defined(MBEDTLS_SHA512_SMALLER)
+ for( i = 0; i < 80; i++ )
+ {
+ if( i < 16 )
+ {
+ local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
+ }
+ else
+ {
+ local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
+ S0(local.W[i - 15]) + local.W[i - 16];
+ }
+
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
+
+ local.temp1 = local.A[7]; local.A[7] = local.A[6];
+ local.A[6] = local.A[5]; local.A[5] = local.A[4];
+ local.A[4] = local.A[3]; local.A[3] = local.A[2];
+ local.A[2] = local.A[1]; local.A[1] = local.A[0];
+ local.A[0] = local.temp1;
+ }
+#else /* MBEDTLS_SHA512_SMALLER */
for( i = 0; i < 16; i++ )
{
- GET_UINT64_BE( local.W[i], data, i << 3 );
+ local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
}
for( ; i < 80; i++ )
{
local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
- S0(local.W[i - 15]) + local.W[i - 16];
+ S0(local.W[i - 15]) + local.W[i - 16];
}
- local.A = ctx->state[0];
- local.B = ctx->state[1];
- local.C = ctx->state[2];
- local.D = ctx->state[3];
- local.E = ctx->state[4];
- local.F = ctx->state[5];
- local.G = ctx->state[6];
- local.H = ctx->state[7];
i = 0;
-
do
{
- P( local.A, local.B, local.C, local.D, local.E,
- local.F, local.G, local.H, local.W[i], K[i] ); i++;
- P( local.H, local.A, local.B, local.C, local.D,
- local.E, local.F, local.G, local.W[i], K[i] ); i++;
- P( local.G, local.H, local.A, local.B, local.C,
- local.D, local.E, local.F, local.W[i], K[i] ); i++;
- P( local.F, local.G, local.H, local.A, local.B,
- local.C, local.D, local.E, local.W[i], K[i] ); i++;
- P( local.E, local.F, local.G, local.H, local.A,
- local.B, local.C, local.D, local.W[i], K[i] ); i++;
- P( local.D, local.E, local.F, local.G, local.H,
- local.A, local.B, local.C, local.W[i], K[i] ); i++;
- P( local.C, local.D, local.E, local.F, local.G,
- local.H, local.A, local.B, local.W[i], K[i] ); i++;
- P( local.B, local.C, local.D, local.E, local.F,
- local.G, local.H, local.A, local.W[i], K[i] ); i++;
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
+ P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
+ local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
+ P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
+ local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
+ P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
+ local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
+ P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
+ local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
+ P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
+ local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
+ P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
+ local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
+ P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
+ local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
}
while( i < 80 );
+#endif /* MBEDTLS_SHA512_SMALLER */
- ctx->state[0] += local.A;
- ctx->state[1] += local.B;
- ctx->state[2] += local.C;
- ctx->state[3] += local.D;
- ctx->state[4] += local.E;
- ctx->state[5] += local.F;
- ctx->state[6] += local.G;
- ctx->state[7] += local.H;
+ for( i = 0; i < 8; i++ )
+ ctx->state[i] += local.A[i];
/* Zeroise buffers and variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &local, sizeof( local ) );
@@ -345,7 +315,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
unsigned int left;
@@ -405,7 +375,7 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
unsigned char output[64] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned used;
uint64_t high, low;
@@ -442,8 +412,8 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT64_BE( high, ctx->buffer, 112 );
- PUT_UINT64_BE( low, ctx->buffer, 120 );
+ sha512_put_uint64_be( high, ctx->buffer, 112 );
+ sha512_put_uint64_be( low, ctx->buffer, 120 );
if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@@ -451,17 +421,19 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
/*
* Output final state
*/
- PUT_UINT64_BE( ctx->state[0], output, 0 );
- PUT_UINT64_BE( ctx->state[1], output, 8 );
- PUT_UINT64_BE( ctx->state[2], output, 16 );
- PUT_UINT64_BE( ctx->state[3], output, 24 );
- PUT_UINT64_BE( ctx->state[4], output, 32 );
- PUT_UINT64_BE( ctx->state[5], output, 40 );
-
+ sha512_put_uint64_be( ctx->state[0], output, 0 );
+ sha512_put_uint64_be( ctx->state[1], output, 8 );
+ sha512_put_uint64_be( ctx->state[2], output, 16 );
+ sha512_put_uint64_be( ctx->state[3], output, 24 );
+ sha512_put_uint64_be( ctx->state[4], output, 32 );
+ sha512_put_uint64_be( ctx->state[5], output, 40 );
+
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
if( ctx->is384 == 0 )
+#endif
{
- PUT_UINT64_BE( ctx->state[6], output, 48 );
- PUT_UINT64_BE( ctx->state[7], output, 56 );
+ sha512_put_uint64_be( ctx->state[6], output, 48 );
+ sha512_put_uint64_be( ctx->state[7], output, 56 );
}
return( 0 );
@@ -485,10 +457,14 @@ int mbedtls_sha512_ret( const unsigned char *input,
unsigned char output[64],
int is384 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha512_context ctx;
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+#else
+ SHA512_VALIDATE_RET( is384 == 0 );
+#endif
SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
@@ -536,8 +512,9 @@ static const size_t sha512_test_buflen[3] =
3, 112, 1000
};
-static const unsigned char sha512_test_sum[6][64] =
+static const unsigned char sha512_test_sum[][64] =
{
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
/*
* SHA-384 test vectors
*/
@@ -559,6 +536,7 @@ static const unsigned char sha512_test_sum[6][64] =
0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
+#endif /* !MBEDTLS_SHA512_NO_SHA384 */
/*
* SHA-512 test vectors
@@ -589,6 +567,8 @@ static const unsigned char sha512_test_sum[6][64] =
0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
};
+#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
+
/*
* Checkup routine
*/
@@ -610,10 +590,14 @@ int mbedtls_sha512_self_test( int verbose )
mbedtls_sha512_init( &ctx );
- for( i = 0; i < 6; i++ )
+ for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
{
j = i % 3;
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
k = i < 3;
+#else
+ k = 0;
+#endif
if( verbose != 0 )
mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
@@ -669,6 +653,8 @@ exit:
return( ret );
}
+#undef ARRAY_LENGTH
+
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_SHA512_C */
diff --git a/thirdparty/mbedtls/library/ssl_cache.c b/thirdparty/mbedtls/library/ssl_cache.c
index 1d2558a189..32188cf3f6 100644
--- a/thirdparty/mbedtls/library/ssl_cache.c
+++ b/thirdparty/mbedtls/library/ssl_cache.c
@@ -2,13 +2,7 @@
* SSL session cache implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,38 +15,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* These session callbacks use a simple chained list
* to store and retrieve the session information.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_CACHE_C)
@@ -65,6 +34,7 @@
#endif
#include "mbedtls/ssl_cache.h"
+#include "mbedtls/ssl_internal.h"
#include <string.h>
@@ -108,25 +78,31 @@ int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
continue;
#endif
- if( session->ciphersuite != entry->session.ciphersuite ||
- session->compression != entry->session.compression ||
- session->id_len != entry->session.id_len )
- continue;
-
- if( memcmp( session->id, entry->session.id,
+ if( session->id_len != entry->session.id_len ||
+ memcmp( session->id, entry->session.id,
entry->session.id_len ) != 0 )
+ {
continue;
+ }
- memcpy( session->master, entry->session.master, 48 );
-
- session->verify_result = entry->session.verify_result;
+ ret = mbedtls_ssl_session_copy( session, &entry->session );
+ if( ret != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/*
* Restore peer certificate (without rest of the original chain)
*/
if( entry->peer_cert.p != NULL )
{
+ /* `session->peer_cert` is NULL after the call to
+ * mbedtls_ssl_session_copy(), because cache entries
+ * have the `peer_cert` field set to NULL. */
+
if( ( session->peer_cert = mbedtls_calloc( 1,
sizeof(mbedtls_x509_crt) ) ) == NULL )
{
@@ -144,7 +120,7 @@ int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
goto exit;
}
}
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
ret = 0;
goto exit;
@@ -264,9 +240,8 @@ int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
#endif
}
- memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) );
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/*
* If we're reusing an entry, free its certificate first
*/
@@ -275,26 +250,43 @@ int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
mbedtls_free( cur->peer_cert.p );
memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) );
}
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
+ /* Copy the entire session; this temporarily makes a copy of the
+ * X.509 CRT structure even though we only want to store the raw CRT.
+ * This inefficiency will go away as soon as we implement on-demand
+ * parsing of CRTs, in which case there's no need for the `peer_cert`
+ * field anymore in the first place, and we're done after this call. */
+ ret = mbedtls_ssl_session_copy( &cur->session, session );
+ if( ret != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
- /*
- * Store peer certificate
- */
- if( session->peer_cert != NULL )
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* If present, free the X.509 structure and only store the raw CRT data. */
+ if( cur->session.peer_cert != NULL )
{
- cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len );
+ cur->peer_cert.p =
+ mbedtls_calloc( 1, cur->session.peer_cert->raw.len );
if( cur->peer_cert.p == NULL )
{
ret = 1;
goto exit;
}
- memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
- session->peer_cert->raw.len );
+ memcpy( cur->peer_cert.p,
+ cur->session.peer_cert->raw.p,
+ cur->session.peer_cert->raw.len );
cur->peer_cert.len = session->peer_cert->raw.len;
+ mbedtls_x509_crt_free( cur->session.peer_cert );
+ mbedtls_free( cur->session.peer_cert );
cur->session.peer_cert = NULL;
}
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
ret = 0;
@@ -336,9 +328,10 @@ void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
mbedtls_ssl_session_free( &prv->session );
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
mbedtls_free( prv->peer_cert.p );
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
mbedtls_free( prv );
}
diff --git a/thirdparty/mbedtls/library/ssl_ciphersuites.c b/thirdparty/mbedtls/library/ssl_ciphersuites.c
index 01df17a5f3..3826ad27fa 100644
--- a/thirdparty/mbedtls/library/ssl_ciphersuites.c
+++ b/thirdparty/mbedtls/library/ssl_ciphersuites.c
@@ -4,13 +4,7 @@
* \brief SSL ciphersuites for mbed TLS
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,34 +17,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_TLS_C)
@@ -65,6 +34,11 @@
#include <string.h>
+#undef HAVE_SHA384
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#define HAVE_SHA384
+#endif
+
/*
* Ordered from most preferred to least preferred in terms of security.
*
@@ -442,7 +416,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
@@ -457,7 +431,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_GCM_C */
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_CCM_C)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM",
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
@@ -491,13 +465,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -508,13 +482,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -583,7 +557,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
@@ -598,7 +572,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_GCM_C */
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_CAMELLIA_C)
@@ -610,13 +584,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -627,13 +601,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -672,13 +646,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
#if defined(MBEDTLS_AES_C)
-#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
+#if defined(HAVE_SHA384) && defined(MBEDTLS_GCM_C)
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */
+#endif /* HAVE_SHA384 && MBEDTLS_GCM_C */
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_GCM_C)
@@ -782,13 +756,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -807,13 +781,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
#if defined(MBEDTLS_AES_C)
-#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
+#if defined(HAVE_SHA384) && defined(MBEDTLS_GCM_C)
{ MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */
+#endif /* HAVE_SHA384 && MBEDTLS_GCM_C */
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_GCM_C)
@@ -918,13 +892,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -991,7 +965,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
{ MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
@@ -1006,7 +980,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_GCM_C */
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_CAMELLIA_C)
@@ -1018,13 +992,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1035,13 +1009,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1110,7 +1084,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
@@ -1125,7 +1099,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_GCM_C */
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_CAMELLIA_C)
@@ -1137,13 +1111,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1154,13 +1128,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1208,13 +1182,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1226,13 +1200,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_SHA1_C)
{ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA",
@@ -1282,13 +1256,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1300,13 +1274,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1344,13 +1318,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1362,13 +1336,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_SHA1_C)
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA",
@@ -1418,13 +1392,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1436,13 +1410,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1481,13 +1455,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_SHA1_C)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA",
@@ -1515,13 +1489,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1559,13 +1533,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1577,13 +1551,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_SHA1_C)
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA",
@@ -1611,13 +1585,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1629,13 +1603,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1719,7 +1693,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_CIPHERSUITE_WEAK },
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384",
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
@@ -1745,7 +1719,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_CIPHERSUITE_WEAK },
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384",
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
@@ -1771,7 +1745,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_CIPHERSUITE_WEAK },
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384",
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
@@ -1797,7 +1771,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_CIPHERSUITE_WEAK },
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384",
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
@@ -1836,7 +1810,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
@@ -1844,7 +1818,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
@@ -1873,7 +1847,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
@@ -1881,7 +1855,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
@@ -1910,7 +1884,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384,MBEDTLS_KEY_EXCHANGE_PSK,
@@ -1918,7 +1892,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
@@ -1947,7 +1921,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
@@ -1955,7 +1929,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
@@ -1984,7 +1958,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
@@ -1992,7 +1966,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
@@ -2021,7 +1995,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
@@ -2042,7 +2016,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
@@ -2050,7 +2024,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
@@ -2079,7 +2053,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
@@ -2087,7 +2061,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
@@ -2116,7 +2090,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
@@ -2124,7 +2098,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
@@ -2153,7 +2127,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
@@ -2161,7 +2135,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
@@ -2378,7 +2352,7 @@ int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -2393,6 +2367,6 @@ int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
return( 0 );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#endif /* MBEDTLS_SSL_TLS_C */
diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c
index b977e5b7b1..b87879ce6a 100644
--- a/thirdparty/mbedtls/library/ssl_cli.c
+++ b/thirdparty/mbedtls/library/ssl_cli.c
@@ -2,13 +2,7 @@
* SSLv3/TLSv1 client-side functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_CLI_C)
@@ -60,9 +29,16 @@
#define mbedtls_free free
#endif
-#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#include "psa/crypto.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#include <string.h>
@@ -76,6 +52,44 @@
#include "mbedtls/platform_util.h"
#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf )
+{
+ if( conf->psk_identity == NULL ||
+ conf->psk_identity_len == 0 )
+ {
+ return( 0 );
+ }
+
+ if( conf->psk != NULL && conf->psk_len != 0 )
+ return( 1 );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
+ return( 1 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf )
+{
+ if( conf->psk_identity == NULL ||
+ conf->psk_identity_len == 0 )
+ {
+ return( 0 );
+ }
+
+ if( conf->psk != NULL && conf->psk_len != 0 )
+ return( 1 );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
@@ -124,18 +138,19 @@ static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
* } ServerNameList;
*
*/
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SERVERNAME, p, 0 );
+ p += 2;
+
+ MBEDTLS_PUT_UINT16_BE( hostname_len + 5, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( hostname_len + 3, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF );
+ *p++ = MBEDTLS_BYTE_0( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
- *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( hostname_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( hostname_len, p, 0 );
+ p += 2;
memcpy( p, ssl->hostname, hostname_len );
@@ -169,14 +184,12 @@ static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
/*
* Secure renegotiation
*/
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0 );
+ p += 2;
*p++ = 0x00;
- *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
- *p++ = ssl->verify_data_len & 0xFF;
+ *p++ = MBEDTLS_BYTE_0( ssl->verify_data_len + 1 );
+ *p++ = MBEDTLS_BYTE_0( ssl->verify_data_len );
memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
@@ -190,7 +203,7 @@ static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
* Only if we handle at least one key exchange that needs signatures.
*/
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -271,21 +284,21 @@ static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
* SignatureAndHashAlgorithm
* supported_signature_algorithms<2..2^16-2>;
*/
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( sig_alg_len + 2, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( sig_alg_len, p, 0 );
+ p += 2;
*olen = 6 + sig_alg_len;
return( 0 );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -342,20 +355,18 @@ static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
grp_id++ )
{
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
- elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
- elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
+ elliptic_curve_list[elliptic_curve_len++] = MBEDTLS_BYTE_1( info->tls_id );
+ elliptic_curve_list[elliptic_curve_len++] = MBEDTLS_BYTE_0( info->tls_id );
}
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( elliptic_curve_len + 2, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( elliptic_curve_len, p, 0 );
+ p += 2;
*olen = 6 + elliptic_curve_len;
@@ -376,10 +387,8 @@ static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
( "client hello, adding supported_point_formats extension" ) );
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 2;
@@ -400,7 +409,7 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
const unsigned char *end,
size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = buf;
size_t kkpp_len;
@@ -415,8 +424,8 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 );
+ p += 2;
/*
* We may need to send ClientHello multiple times for Hello verification.
@@ -458,8 +467,8 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
}
- *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 );
+ p += 2;
*olen = kkpp_len + 4;
@@ -467,6 +476,52 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+static int ssl_write_cid_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t ext_len;
+
+ /*
+ * Quoting draft-ietf-tls-dtls-connection-id-05
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
+ *
+ * struct {
+ * opaque cid<0..2^8-1>;
+ * } ConnectionId;
+ */
+
+ *olen = 0;
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
+ {
+ return( 0 );
+ }
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding CID extension" ) );
+
+ /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
+ * which is at most 255, so the increment cannot overflow. */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, (unsigned)( ssl->own_cid_len + 5 ) );
+
+ /* Add extension ID + size */
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_CID, p, 0 );
+ p += 2;
+ ext_len = (size_t) ssl->own_cid_len + 1;
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2;
+
+ *p++ = (uint8_t) ssl->own_cid_len;
+ memcpy( p, ssl->own_cid, ssl->own_cid_len );
+
+ *olen = ssl->own_cid_len + 5;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
@@ -485,10 +540,8 @@ static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 1;
@@ -519,8 +572,8 @@ static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_TRUNCATED_HMAC, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -550,8 +603,8 @@ static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -581,10 +634,8 @@ static int ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -615,11 +666,11 @@ static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
/* The addition is safe here since the ticket length is 16 bit. */
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 + tlen );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( tlen ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( tlen, p, 0 );
+ p += 2;
*olen = 4;
@@ -627,7 +678,7 @@ static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
return( 0 );
MBEDTLS_SSL_DEBUG_MSG( 3,
- ( "sending session ticket of length %d", tlen ) );
+ ( "sending session ticket of length %" MBEDTLS_PRINTF_SIZET, tlen ) );
memcpy( p, ssl->session_negotiate->ticket, tlen );
@@ -659,8 +710,8 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + alpnlen );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ALPN, p, 0 );
+ p += 2;
/*
* opaque ProtocolName<1..2^8-1>;
@@ -687,23 +738,139 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
*olen = p - buf;
/* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
- buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
- buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( *olen - 6, buf, 4 );
/* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
- buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
- buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( *olen - 4, buf, 2 );
return( 0 );
}
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t protection_profiles_index = 0, ext_len = 0;
+ uint16_t mki_len = 0, profile_value = 0;
+
+ *olen = 0;
+
+ if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+ ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+ ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+ {
+ return( 0 );
+ }
+
+ /* RFC 5764 section 4.1.1
+ * uint8 SRTPProtectionProfile[2];
+ *
+ * struct {
+ * SRTPProtectionProfiles SRTPProtectionProfiles;
+ * opaque srtp_mki<0..255>;
+ * } UseSRTPData;
+ * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+ */
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+ {
+ mki_len = ssl->dtls_srtp_info.mki_len;
+ }
+ /* Extension length = 2 bytes for profiles length,
+ * ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ),
+ * 1 byte for srtp_mki vector length and the mki_len value
+ */
+ ext_len = 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding use_srtp extension" ) );
+
+ /* Check there is room in the buffer for the extension + 4 bytes
+ * - the extension tag (2 bytes)
+ * - the extension length (2 bytes)
+ */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, ext_len + 4 );
+
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_USE_SRTP, p, 0 );
+ p += 2;
+
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2;
+
+ /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
+ /* micro-optimization:
+ * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH
+ * which is lower than 127, so the upper byte of the length is always 0
+ * For the documentation, the more generic code is left in comments
+ * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
+ * >> 8 ) & 0xFF );
+ */
+ *p++ = 0;
+ *p++ = MBEDTLS_BYTE_0( 2 * ssl->conf->dtls_srtp_profile_list_len );
+
+ for( protection_profiles_index=0;
+ protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
+ protection_profiles_index++ )
+ {
+ profile_value = mbedtls_ssl_check_srtp_profile_value
+ ( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] );
+ if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
+ profile_value ) );
+ MBEDTLS_PUT_UINT16_BE( profile_value, p, 0 );
+ p += 2;
+ }
+ else
+ {
+ /*
+ * Note: we shall never arrive here as protection profiles
+ * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function
+ */
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, "
+ "illegal DTLS-SRTP protection profile %d",
+ ssl->conf->dtls_srtp_profile_list[protection_profiles_index]
+ ) );
+ return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
+ }
+ }
+
+ *p++ = mki_len & 0xFF;
+
+ if( mki_len != 0 )
+ {
+ memcpy( p, ssl->dtls_srtp_info.mki_value, mki_len );
+ /*
+ * Increment p to point to the current position.
+ */
+ p += mki_len;
+ MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki", ssl->dtls_srtp_info.mki_value,
+ ssl->dtls_srtp_info.mki_len );
+ }
+
+ /*
+ * total extension length: extension type (2 bytes)
+ * + extension length (2 bytes)
+ * + protection profile length (2 bytes)
+ * + 2 * number of protection profiles
+ * + srtp_mki vector length(1 byte)
+ * + mki value
+ */
+ *olen = p - buf;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/*
* Generate random bytes for ClientHello
*/
static int ssl_generate_random( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = ssl->handshake->randbytes;
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t t;
@@ -722,12 +889,11 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_HAVE_TIME)
t = mbedtls_time( NULL );
- *p++ = (unsigned char)( t >> 24 );
- *p++ = (unsigned char)( t >> 16 );
- *p++ = (unsigned char)( t >> 8 );
- *p++ = (unsigned char)( t );
+ MBEDTLS_PUT_UINT32_BE( t, p, 0 );
+ p += 4;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
+ (long long) t ) );
#else
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
return( ret );
@@ -782,12 +948,21 @@ static int ssl_validate_ciphersuite(
return( 1 );
#endif
+ /* Don't suggest PSK-based ciphersuite if no PSK is available. */
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+ if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
+ ssl_conf_has_static_psk( ssl->conf ) == 0 )
+ {
+ return( 1 );
+ }
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+
return( 0 );
}
static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n, olen, ext_len = 0;
unsigned char *buf;
@@ -927,7 +1102,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
for( i = 0; i < n; i++ )
*p++ = ssl->session_negotiate->id[i];
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
/*
@@ -994,8 +1169,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ssl->conf->max_minor_ver ) != 0 )
continue;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
- ciphersuites[i] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %#04x (%s)",
+ (unsigned int)ciphersuites[i], ciphersuite_info->name ) );
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1005,12 +1180,12 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
n++;
- *p++ = (unsigned char)( ciphersuites[i] >> 8 );
- *p++ = (unsigned char)( ciphersuites[i] );
+ MBEDTLS_PUT_UINT16_BE( ciphersuites[i], p, 0 );
+ p += 2;
}
MBEDTLS_SSL_DEBUG_MSG( 3,
- ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) );
+ ( "client hello, got %" MBEDTLS_PRINTF_SIZET " ciphersuites (excluding SCSVs)", n ) );
/*
* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
@@ -1021,8 +1196,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) );
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
- *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
- *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO, p, 0 );
+ p += 2;
n++;
}
@@ -1033,8 +1208,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
- *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
- *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_SSL_FALLBACK_SCSV_VALUE, p, 0 );
+ p += 2;
n++;
}
#endif
@@ -1109,7 +1284,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
if( ( ret = ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len,
end, &olen ) ) != 0 )
{
@@ -1151,6 +1326,15 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( ( ret = ssl_write_cid_ext( ssl, p + 2 + ext_len, end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_cid_ext", ret );
+ return( ret );
+ }
+ ext_len += olen;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
if( ( ret = ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len,
end, &olen ) ) != 0 )
@@ -1201,6 +1385,16 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret );
+ return( ret );
+ }
+ ext_len += olen;
+#endif
+
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len,
end, &olen ) ) != 0 )
@@ -1214,16 +1408,15 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
/* olen unused if all extensions are disabled */
((void) olen);
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
ext_len ) );
if( ext_len > 0 )
{
/* No need to check for space here, because the extension
* writing functions already took care of that. */
- *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ext_len ) & 0xFF );
- p += ext_len;
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2 + ext_len;
}
ssl->out_msglen = p - buf;
@@ -1267,9 +1460,9 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
/* Check verify-data in constant-time. The length OTOH is no secret */
if( len != 1 + ssl->verify_data_len * 2 ||
buf[0] != ssl->verify_data_len * 2 ||
- mbedtls_ssl_safer_memcmp( buf + 1,
+ mbedtls_ct_memcmp( buf + 1,
ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
- mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
+ mbedtls_ct_memcmp( buf + 1 + ssl->verify_data_len,
ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -1351,6 +1544,62 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ size_t peer_cid_len;
+
+ if( /* CID extension only makes sense in DTLS */
+ ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ /* The server must only send the CID extension if we have offered it. */
+ ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension unexpected" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ if( len == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ peer_cid_len = *buf++;
+ len--;
+
+ if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ if( len != peer_cid_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
+ ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len;
+ memcpy( ssl->handshake->peer_cid, buf, peer_cid_len );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Server CID", buf, peer_cid_len );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
@@ -1479,9 +1728,9 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
+ if( ssl->handshake->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
@@ -1578,6 +1827,123 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET;
+ size_t i, mki_len = 0;
+ uint16_t server_protection_profile_value = 0;
+
+ /* If use_srtp is not configured, just ignore the extension */
+ if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+ ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+ ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+ return( 0 );
+
+ /* RFC 5764 section 4.1.1
+ * uint8 SRTPProtectionProfile[2];
+ *
+ * struct {
+ * SRTPProtectionProfiles SRTPProtectionProfiles;
+ * opaque srtp_mki<0..255>;
+ * } UseSRTPData;
+
+ * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+ *
+ */
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+ {
+ mki_len = ssl->dtls_srtp_info.mki_len;
+ }
+
+ /*
+ * Length is 5 + optional mki_value : one protection profile length (2 bytes)
+ * + protection profile (2 bytes)
+ * + mki_len(1 byte)
+ * and optional srtp_mki
+ */
+ if( ( len < 5 ) || ( len != ( buf[4] + 5u ) ) )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+
+ /*
+ * get the server protection profile
+ */
+
+ /*
+ * protection profile length must be 0x0002 as we must have only
+ * one protection profile in server Hello
+ */
+ if( ( buf[0] != 0 ) || ( buf[1] != 2 ) )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+
+ server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
+ server_protection = mbedtls_ssl_check_srtp_profile_value(
+ server_protection_profile_value );
+ if( server_protection != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s",
+ mbedtls_ssl_get_srtp_profile_as_string(
+ server_protection ) ) );
+ }
+
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
+
+ /*
+ * Check we have the server profile in our list
+ */
+ for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
+ {
+ if( server_protection == ssl->conf->dtls_srtp_profile_list[i] )
+ {
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
+ mbedtls_ssl_get_srtp_profile_as_string(
+ server_protection ) ) );
+ break;
+ }
+ }
+
+ /* If no match was found : server problem, it shall never answer with incompatible profile */
+ if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ /* If server does not use mki in its reply, make sure the client won't keep
+ * one as negotiated */
+ if( len == 5 )
+ {
+ ssl->dtls_srtp_info.mki_len = 0;
+ }
+
+ /*
+ * RFC5764:
+ * If the client detects a nonzero-length MKI in the server's response
+ * that is different than the one the client offered, then the client
+ * MUST abort the handshake and SHOULD send an invalid_parameter alert.
+ */
+ if( len > 5 && ( buf[4] != mki_len ||
+ ( memcmp( ssl->dtls_srtp_info.mki_value, &buf[5], mki_len ) ) ) )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+#if defined (MBEDTLS_DEBUG_C)
+ if( len > 5 )
+ {
+ MBEDTLS_SSL_DEBUG_BUF( 3, "received mki", ssl->dtls_srtp_info.mki_value,
+ ssl->dtls_srtp_info.mki_len );
+ }
+#endif
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/*
* Parse HelloVerifyRequest. Only called after verifying the HS type.
*/
@@ -1683,8 +2049,6 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
- buf = ssl->in_msg;
-
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{
/* No alert on a read error. */
@@ -1692,6 +2056,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
return( ret );
}
+ buf = ssl->in_msg;
+
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{
#if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -1788,10 +2154,10 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu",
- ( (uint32_t) buf[2] << 24 ) |
- ( (uint32_t) buf[3] << 16 ) |
- ( (uint32_t) buf[4] << 8 ) |
- ( (uint32_t) buf[5] ) ) );
+ ( (unsigned long) buf[2] << 24 ) |
+ ( (unsigned long) buf[3] << 16 ) |
+ ( (unsigned long) buf[4] << 8 ) |
+ ( (unsigned long) buf[5] ) ) );
memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
@@ -1870,22 +2236,19 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
/*
* Initialize update checksum functions
*/
- ssl->transform_negotiate->ciphersuite_info =
- mbedtls_ssl_ciphersuite_from_id( i );
-
- if( ssl->transform_negotiate->ciphersuite_info == NULL )
+ ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
+ if( ssl->handshake->ciphersuite_info == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
- ( "ciphersuite info for %04x not found", i ) );
+ ( "ciphersuite info for %04x not found", (unsigned int)i ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- mbedtls_ssl_optimize_checksum( ssl,
- ssl->transform_negotiate->ciphersuite_info );
+ mbedtls_ssl_optimize_checksum( ssl, ssl->handshake->ciphersuite_info );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
/*
@@ -1928,7 +2291,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->handshake->resume ? "a" : "no" ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", (unsigned) i ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d",
buf[37 + n] ) );
@@ -1971,7 +2334,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3,
( "server hello, chosen ciphersuite: %s", suite_info->name ) );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA &&
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
@@ -1997,7 +2360,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
ext = buf + 40 + n;
MBEDTLS_SSL_DEBUG_MSG( 2,
- ( "server hello, total extension length: %d", ext_len ) );
+ ( "server hello, total extension length: %" MBEDTLS_PRINTF_SIZET, ext_len ) );
while( ext_len )
{
@@ -2056,6 +2419,20 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
break;
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ case MBEDTLS_TLS_EXT_CID:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) );
+
+ if( ( ret = ssl_parse_cid_ext( ssl,
+ ext + 4,
+ ext_size ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ break;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
@@ -2135,9 +2512,19 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
break;
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ case MBEDTLS_TLS_EXT_USE_SRTP:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+
+ if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 )
+ return( ret );
+
+ break;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
default:
MBEDTLS_SSL_DEBUG_MSG( 3,
- ( "unknown extension found: %d (ignoring)", ext_id ) );
+ ( "unknown extension found: %u (ignoring)", ext_id ) );
}
ext_len -= 4 + ext_size;
@@ -2230,8 +2617,8 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl,
dhm_actual_bitlen = mbedtls_mpi_bitlen( &ssl->handshake->dhm_ctx.P );
if( dhm_actual_bitlen < ssl->conf->dhm_min_bitlen )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %u < %u",
- (unsigned) dhm_actual_bitlen,
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u",
+ dhm_actual_bitlen,
ssl->conf->dhm_min_bitlen ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@@ -2288,6 +2675,68 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) )
+static int ssl_parse_server_ecdh_params_psa( mbedtls_ssl_context *ssl,
+ unsigned char **p,
+ unsigned char *end )
+{
+ uint16_t tls_id;
+ size_t ecdh_bits = 0;
+ uint8_t ecpoint_len;
+ mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+ /*
+ * Parse ECC group
+ */
+
+ if( end - *p < 4 )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
+ /* First byte is curve_type; only named_curve is handled */
+ if( *(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
+ /* Next two bytes are the namedcurve value */
+ tls_id = *(*p)++;
+ tls_id <<= 8;
+ tls_id |= *(*p)++;
+
+ /* Convert EC group to PSA key type. */
+ if( ( handshake->ecdh_psa_type =
+ mbedtls_psa_parse_tls_ecc_group( tls_id, &ecdh_bits ) ) == 0 )
+ {
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+ }
+ if( ecdh_bits > 0xffff )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+ handshake->ecdh_bits = (uint16_t) ecdh_bits;
+
+ /*
+ * Put peer's ECDH public key in the format understood by PSA.
+ */
+
+ ecpoint_len = *(*p)++;
+ if( (size_t)( end - *p ) < ecpoint_len )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
+ if( mbedtls_psa_tls_ecpoint_to_psa_ec(
+ *p, ecpoint_len,
+ handshake->ecdh_psa_peerkey,
+ sizeof( handshake->ecdh_psa_peerkey ),
+ &handshake->ecdh_psa_peerkey_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ *p += ecpoint_len;
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */
+
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
@@ -2309,7 +2758,7 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
(const unsigned char **) p, end ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
@@ -2329,13 +2778,13 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- size_t len;
+ uint16_t len;
((void) ssl);
/*
@@ -2352,7 +2801,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
len = (*p)[0] << 8 | (*p)[1];
*p += 2;
- if( end - (*p) < (int) len )
+ if( end - (*p) < len )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "bad server key exchange message (psk_identity_hint length)" ) );
@@ -2369,7 +2818,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
return( ret );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
@@ -2380,9 +2829,10 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
size_t offset, size_t *olen,
size_t pms_offset )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
unsigned char *p = ssl->handshake->premaster + pms_offset;
+ mbedtls_pk_context * peer_pk;
if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
@@ -2409,23 +2859,28 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
ssl->handshake->pmslen = 48;
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ /* Should never happen */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* Now write it out, encrypted
*/
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_RSA ) )
+ if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_RSA ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
- if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
+ if( ( ret = mbedtls_pk_encrypt( peer_pk,
p, ssl->handshake->pmslen,
ssl->out_msg + offset + len_bytes, olen,
MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
@@ -2439,12 +2894,15 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( len_bytes == 2 )
{
- ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
- ssl->out_msg[offset+1] = (unsigned char)( *olen );
+ MBEDTLS_PUT_UINT16_BE( *olen, ssl->out_msg, offset );
*olen += 2;
}
#endif
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* We don't need the peer's public key anymore. Free it. */
+ mbedtls_pk_free( peer_pk );
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
@@ -2522,23 +2980,29 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_ecp_keypair *peer_key;
+ mbedtls_pk_context * peer_pk;
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ /* Should never happen */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_ECKEY ) )
+ if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
- peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
+ peer_key = mbedtls_pk_ec( *peer_pk );
if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
MBEDTLS_ECDH_THEIRS ) ) != 0 )
@@ -2553,6 +3017,13 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* We don't need the peer's public key anymore. Free it,
+ * so that more RAM is available for upcoming expensive
+ * operations like ECDHE. */
+ mbedtls_pk_free( peer_pk );
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
return( ret );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
@@ -2560,9 +3031,9 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
unsigned char *p = NULL, *end = NULL;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
@@ -2602,7 +3073,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled &&
ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing )
{
@@ -2651,7 +3122,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing;
@@ -2661,7 +3132,7 @@ start_processing:
end = ssl->in_msg + ssl->in_hslen;
MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
@@ -2677,7 +3148,7 @@ start_processing:
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
} /* FALLTROUGH */
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
@@ -2705,6 +3176,26 @@ start_processing:
else
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) )
+ if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
+ ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
+ {
+ if( ssl_parse_server_ecdh_params_psa( ssl, &p, end ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+ }
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
@@ -2748,17 +3239,23 @@ start_processing:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
{
size_t sig_len, hashlen;
- unsigned char hash[64];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ unsigned char hash[PSA_HASH_MAX_SIZE];
+#else
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+#endif
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
size_t params_len = p - params;
void *rs_ctx = NULL;
+ mbedtls_pk_context * peer_pk;
+
/*
* Handle the digitally-signed structure
*/
@@ -2872,21 +3369,22 @@ start_processing:
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- mbedtls_ssl_send_alert_message(
- ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ /* Should never happen */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* Verify signature
*/
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- pk_alg ) )
+ if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message(
@@ -2896,16 +3394,15 @@ start_processing:
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
rs_ctx = &ssl->handshake->ecrs_ctx.pk;
#endif
- if( ( ret = mbedtls_pk_verify_restartable(
- &ssl->session_negotiate->peer_cert->pk,
+ if( ( ret = mbedtls_pk_verify_restartable( peer_pk,
md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 )
{
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
#endif
mbedtls_ssl_send_alert_message(
@@ -2913,14 +3410,21 @@ start_processing:
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret );
}
+
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* We don't need the peer's public key anymore. Free it,
+ * so that more RAM is available for upcoming expensive
+ * operations like ECDHE. */
+ mbedtls_pk_free( peer_pk );
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
exit:
ssl->state++;
@@ -2930,11 +3434,11 @@ exit:
return( 0 );
}
-#if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED)
+#if ! defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@@ -2948,15 +3452,15 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
+#else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *buf;
size_t n = 0;
size_t cert_type_len = 0, dn_len = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@@ -3118,11 +3622,11 @@ exit:
return( 0 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
@@ -3161,10 +3665,12 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
{
- int ret;
- size_t i, n;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ size_t header_len;
+ size_t content_len;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
@@ -3174,15 +3680,14 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
/*
* DHM key exchange -- send G^X mod P
*/
- n = ssl->handshake->dhm_ctx.len;
+ content_len = ssl->handshake->dhm_ctx.len;
- ssl->out_msg[4] = (unsigned char)( n >> 8 );
- ssl->out_msg[5] = (unsigned char)( n );
- i = 6;
+ MBEDTLS_PUT_UINT16_BE( content_len, ssl->out_msg, 4 );
+ header_len = 6;
ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- &ssl->out_msg[i], n,
+ &ssl->out_msg[header_len], content_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
@@ -3207,6 +3712,93 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) )
+ if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
+ ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
+ {
+ psa_status_t status;
+ psa_key_attributes_t key_attributes;
+
+ mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+ unsigned char own_pubkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
+ size_t own_pubkey_len;
+ unsigned char *own_pubkey_ecpoint;
+ size_t own_pubkey_ecpoint_len;
+
+ header_len = 4;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform PSA-based ECDH computation." ) );
+
+ /*
+ * Generate EC private key for ECDHE exchange.
+ */
+
+ /* The master secret is obtained from the shared ECDH secret by
+ * applying the TLS 1.2 PRF with a specific salt and label. While
+ * the PSA Crypto API encourages combining key agreement schemes
+ * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not
+ * yet support the provisioning of salt + label to the KDF.
+ * For the time being, we therefore need to split the computation
+ * of the ECDH secret and the application of the TLS 1.2 PRF. */
+ key_attributes = psa_key_attributes_init();
+ psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
+ psa_set_key_algorithm( &key_attributes, PSA_ALG_ECDH );
+ psa_set_key_type( &key_attributes, handshake->ecdh_psa_type );
+ psa_set_key_bits( &key_attributes, handshake->ecdh_bits );
+
+ /* Generate ECDH private key. */
+ status = psa_generate_key( &key_attributes,
+ &handshake->ecdh_psa_privkey );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ /* Export the public part of the ECDH private key from PSA
+ * and convert it to ECPoint format used in ClientKeyExchange. */
+ status = psa_export_public_key( handshake->ecdh_psa_privkey,
+ own_pubkey, sizeof( own_pubkey ),
+ &own_pubkey_len );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ if( mbedtls_psa_tls_psa_ec_to_ecpoint( own_pubkey,
+ own_pubkey_len,
+ &own_pubkey_ecpoint,
+ &own_pubkey_ecpoint_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ /* Copy ECPoint structure to outgoing message buffer. */
+ ssl->out_msg[header_len] = (unsigned char) own_pubkey_ecpoint_len;
+ memcpy( ssl->out_msg + header_len + 1,
+ own_pubkey_ecpoint, own_pubkey_ecpoint_len );
+ content_len = own_pubkey_ecpoint_len + 1;
+
+ /* The ECDH secret is the premaster secret used for key derivation. */
+
+ /* Compute ECDH shared secret. */
+ status = psa_raw_key_agreement( PSA_ALG_ECDH,
+ handshake->ecdh_psa_privkey,
+ handshake->ecdh_psa_peerkey,
+ handshake->ecdh_psa_peerkey_len,
+ ssl->handshake->premaster,
+ sizeof( ssl->handshake->premaster ),
+ &ssl->handshake->pmslen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ status = psa_destroy_key( handshake->ecdh_psa_privkey );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
@@ -3219,9 +3811,9 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
/*
* ECDH key exchange -- send client public value
*/
- i = 4;
+ header_len = 4;
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
{
if( ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret )
@@ -3232,13 +3824,13 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
#endif
ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
- &n,
- &ssl->out_msg[i], 1000,
+ &content_len,
+ &ssl->out_msg[header_len], 1000,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
@@ -3248,16 +3840,16 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Q );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
{
- ssl->handshake->ecrs_n = n;
+ ssl->handshake->ecrs_n = content_len;
ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret;
}
ecdh_calc_secret:
if( ssl->handshake->ecrs_enabled )
- n = ssl->handshake->ecrs_n;
+ content_len = ssl->handshake->ecrs_n;
#endif
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
&ssl->handshake->pmslen,
@@ -3266,7 +3858,7 @@ ecdh_calc_secret:
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
@@ -3281,47 +3873,56 @@ ecdh_calc_secret:
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) )
{
/*
* opaque psk_identity<0..2^16-1>;
*/
- if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
+ if( ssl_conf_has_static_psk( ssl->conf ) == 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+ /* We don't offer PSK suites if we don't have a PSK,
+ * and we check that the server's choice is among the
+ * ciphersuites we offered, so this should never happen. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- i = 4;
- n = ssl->conf->psk_identity_len;
+ header_len = 4;
+ content_len = ssl->conf->psk_identity_len;
- if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ if( header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "psk identity too long or SSL buffer too short" ) );
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
}
- ssl->out_msg[i++] = (unsigned char)( n >> 8 );
- ssl->out_msg[i++] = (unsigned char)( n );
+ ssl->out_msg[header_len++] = MBEDTLS_BYTE_1( content_len );
+ ssl->out_msg[header_len++] = MBEDTLS_BYTE_0( content_len );
- memcpy( ssl->out_msg + i,
+ memcpy( ssl->out_msg + header_len,
ssl->conf->psk_identity,
ssl->conf->psk_identity_len );
- i += ssl->conf->psk_identity_len;
+ header_len += ssl->conf->psk_identity_len;
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
{
- n = 0;
+ content_len = 0;
}
else
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
{
- if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only suites. */
+ if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ if( ( ret = ssl_write_encrypted_pms( ssl, header_len,
+ &content_len, 2 ) ) != 0 )
return( ret );
}
else
@@ -3329,24 +3930,31 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only suites. */
+ if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/*
* ClientDiffieHellmanPublic public (DHM send G^X mod P)
*/
- n = ssl->handshake->dhm_ctx.len;
+ content_len = ssl->handshake->dhm_ctx.len;
- if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ if( header_len + 2 + content_len >
+ MBEDTLS_SSL_OUT_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "psk identity or DHM size too long or SSL buffer too short" ) );
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
}
- ssl->out_msg[i++] = (unsigned char)( n >> 8 );
- ssl->out_msg[i++] = (unsigned char)( n );
+ ssl->out_msg[header_len++] = MBEDTLS_BYTE_1( content_len );
+ ssl->out_msg[header_len++] = MBEDTLS_BYTE_0( content_len );
ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- &ssl->out_msg[i], n,
+ &ssl->out_msg[header_len], content_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
@@ -3359,11 +3967,19 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only suites. */
+ if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/*
* ClientECDiffieHellmanPublic public;
*/
- ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
- &ssl->out_msg[i], MBEDTLS_SSL_OUT_CONTENT_LEN - i,
+ ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
+ &content_len,
+ &ssl->out_msg[header_len],
+ MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
@@ -3381,6 +3997,18 @@ ecdh_calc_secret:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+ if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
+ ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+ ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "skip PMS generation for opaque PSK" ) );
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
ciphersuite_info->key_exchange ) ) != 0 )
{
@@ -3390,12 +4018,13 @@ ecdh_calc_secret:
}
}
else
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
{
- i = 4;
- if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
+ header_len = 4;
+ if( ( ret = ssl_write_encrypted_pms( ssl, header_len,
+ &content_len, 0 ) ) != 0 )
return( ret );
}
else
@@ -3403,10 +4032,12 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
- i = 4;
+ header_len = 4;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
- ssl->out_msg + i, MBEDTLS_SSL_OUT_CONTENT_LEN - i, &n,
+ ssl->out_msg + header_len,
+ MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
+ &content_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
@@ -3431,7 +4062,7 @@ ecdh_calc_secret:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- ssl->out_msglen = i + n;
+ ssl->out_msglen = header_len + content_len;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
@@ -3448,17 +4079,12 @@ ecdh_calc_secret:
return( 0 );
}
-#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
- int ret;
+ ssl->handshake->ciphersuite_info;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
@@ -3468,11 +4094,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
@@ -3482,22 +4104,22 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else
+#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
size_t n = 0, offset = 0;
unsigned char hash[48];
unsigned char *hash_start = hash;
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
- unsigned int hashlen;
+ size_t hashlen;
void *rs_ctx = NULL;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled &&
ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign )
{
@@ -3511,11 +4133,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
@@ -3538,14 +4156,14 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
/*
* Make a signature of the handshake digests
*/
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign;
sign:
#endif
- ssl->handshake->calc_verify( ssl, hash );
+ ssl->handshake->calc_verify( ssl, hash, &hashlen );
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
@@ -3563,7 +4181,6 @@ sign:
* sha_hash
* SHA(handshake_messages);
*/
- hashlen = 36;
md_alg = MBEDTLS_MD_NONE;
/*
@@ -3598,8 +4215,7 @@ sign:
* SHA224 in order to satisfy 'weird' needs from the server
* side.
*/
- if( ssl->transform_negotiate->ciphersuite_info->mac ==
- MBEDTLS_MD_SHA384 )
+ if( ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
{
md_alg = MBEDTLS_MD_SHA384;
ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
@@ -3622,7 +4238,7 @@ sign:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
rs_ctx = &ssl->handshake->ecrs_ctx.pk;
#endif
@@ -3633,15 +4249,14 @@ sign:
ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret );
}
- ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
- ssl->out_msg[5 + offset] = (unsigned char)( n );
+ MBEDTLS_PUT_UINT16_BE( n, ssl->out_msg, offset + 4 );
ssl->out_msglen = 6 + n + offset;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@@ -3659,17 +4274,12 @@ sign:
return( ret );
}
-#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t lifetime;
size_t ticket_len;
unsigned char *ticket;
@@ -3727,7 +4337,7 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
}
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len ) );
/* We're not waiting for a NewSessionTicket message any more */
ssl->handshake->new_session_ticket = 0;
@@ -3740,6 +4350,15 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
if( ticket_len == 0 )
return( 0 );
+ if( ssl->session != NULL && ssl->session->ticket != NULL )
+ {
+ mbedtls_platform_zeroize( ssl->session->ticket,
+ ssl->session->ticket_len );
+ mbedtls_free( ssl->session->ticket );
+ ssl->session->ticket = NULL;
+ ssl->session->ticket_len = 0;
+ }
+
mbedtls_platform_zeroize( ssl->session_negotiate->ticket,
ssl->session_negotiate->ticket_len );
mbedtls_free( ssl->session_negotiate->ticket );
diff --git a/thirdparty/mbedtls/library/ssl_cookie.c b/thirdparty/mbedtls/library/ssl_cookie.c
index 9e2136865d..abf29ae717 100644
--- a/thirdparty/mbedtls/library/ssl_cookie.c
+++ b/thirdparty/mbedtls/library/ssl_cookie.c
@@ -2,13 +2,7 @@
* DTLS cookie callbacks implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,38 +15,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* These session callbacks use a simple chained list
* to store and retrieve the session information.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_COOKIE_C)
@@ -65,7 +34,9 @@
#include "mbedtls/ssl_cookie.h"
#include "mbedtls/ssl_internal.h"
+#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
@@ -129,7 +100,7 @@ int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char key[COOKIE_MD_OUTLEN];
if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 )
@@ -181,7 +152,7 @@ int mbedtls_ssl_cookie_write( void *p_ctx,
unsigned char **p, unsigned char *end,
const unsigned char *cli_id, size_t cli_id_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
unsigned long t;
@@ -196,15 +167,12 @@ int mbedtls_ssl_cookie_write( void *p_ctx,
t = ctx->serial++;
#endif
- (*p)[0] = (unsigned char)( t >> 24 );
- (*p)[1] = (unsigned char)( t >> 16 );
- (*p)[2] = (unsigned char)( t >> 8 );
- (*p)[3] = (unsigned char)( t );
+ MBEDTLS_PUT_UINT32_BE(t, *p, 0);
*p += 4;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret ) );
#endif
ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4,
@@ -212,8 +180,8 @@ int mbedtls_ssl_cookie_write( void *p_ctx,
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
- MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR,
+ MBEDTLS_ERR_THREADING_MUTEX_ERROR ) );
#endif
return( ret );
@@ -240,7 +208,7 @@ int mbedtls_ssl_cookie_check( void *p_ctx,
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret ) );
#endif
if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie,
@@ -250,14 +218,16 @@ int mbedtls_ssl_cookie_check( void *p_ctx,
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- ret = ( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
- MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+ {
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR,
+ MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+ }
#endif
if( ret != 0 )
goto exit;
- if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
+ if( mbedtls_ct_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
{
ret = -1;
goto exit;
diff --git a/thirdparty/mbedtls/library/ssl_msg.c b/thirdparty/mbedtls/library/ssl_msg.c
new file mode 100644
index 0000000000..0b696dd561
--- /dev/null
+++ b/thirdparty/mbedtls/library/ssl_msg.c
@@ -0,0 +1,5922 @@
+/*
+ * Generic SSL/TLS messaging layer functions
+ * (record layer + retransmission state machine)
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * The SSL 3.0 specification was drafted by Netscape in 1996,
+ * and became an IETF standard in 1999.
+ *
+ * http://wp.netscape.com/eng/ssl3/
+ * http://www.ietf.org/rfc/rfc2246.txt
+ * http://www.ietf.org/rfc/rfc4346.txt
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_TLS_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#include "mbedtls/ssl.h"
+#include "mbedtls/ssl_internal.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform_util.h"
+#include "mbedtls/version.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#include "psa/crypto.h"
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#include "mbedtls/oid.h"
+#endif
+
+static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
+
+/*
+ * Start a timer.
+ * Passing millisecs = 0 cancels a running timer.
+ */
+void mbedtls_ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
+{
+ if( ssl->f_set_timer == NULL )
+ return;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
+ ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
+}
+
+/*
+ * Return -1 is timer is expired, 0 if it isn't.
+ */
+int mbedtls_ssl_check_timer( mbedtls_ssl_context *ssl )
+{
+ if( ssl->f_get_timer == NULL )
+ return( 0 );
+
+ if( ssl->f_get_timer( ssl->p_timer ) == 2 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
+ return( -1 );
+ }
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
+ unsigned char *buf,
+ size_t len,
+ mbedtls_record *rec );
+
+int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl,
+ unsigned char *buf,
+ size_t buflen )
+{
+ int ret = 0;
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen );
+
+ /* We don't support record checking in TLS because
+ * (a) there doesn't seem to be a usecase for it, and
+ * (b) In SSLv3 and TLS 1.0, CBC record decryption has state
+ * and we'd need to backup the transform here.
+ */
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
+ {
+ ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+ goto exit;
+ }
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ else
+ {
+ mbedtls_record rec;
+
+ ret = ssl_parse_record_header( ssl, buf, buflen, &rec );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 3, "ssl_parse_record_header", ret );
+ goto exit;
+ }
+
+ if( ssl->transform_in != NULL )
+ {
+ ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, &rec );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 3, "mbedtls_ssl_decrypt_buf", ret );
+ goto exit;
+ }
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+exit:
+ /* On success, we have decrypted the buffer in-place, so make
+ * sure we don't leak any plaintext data. */
+ mbedtls_platform_zeroize( buf, buflen );
+
+ /* For the purpose of this API, treat messages with unexpected CID
+ * as well as such from future epochs as unexpected. */
+ if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
+ ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
+ {
+ ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) );
+ return( ret );
+}
+#endif /* MBEDTLS_SSL_RECORD_CHECKING */
+
+#define SSL_DONT_FORCE_FLUSH 0
+#define SSL_FORCE_FLUSH 1
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+/* Forward declarations for functions related to message buffering. */
+static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
+ uint8_t slot );
+static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
+static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
+static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
+static int ssl_buffer_message( mbedtls_ssl_context *ssl );
+static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
+ mbedtls_record const *rec );
+static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
+
+static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
+{
+ size_t mtu = mbedtls_ssl_get_current_mtu( ssl );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+
+ if( mtu != 0 && mtu < out_buf_len )
+ return( mtu );
+
+ return( out_buf_len );
+}
+
+static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
+{
+ size_t const bytes_written = ssl->out_left;
+ size_t const mtu = ssl_get_maximum_datagram_size( ssl );
+
+ /* Double-check that the write-index hasn't gone
+ * past what we can transmit in a single datagram. */
+ if( bytes_written > mtu )
+ {
+ /* Should never happen... */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ return( (int) ( mtu - bytes_written ) );
+}
+
+static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t remaining, expansion;
+ size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );
+
+ if( max_len > mfl )
+ max_len = mfl;
+
+ /* By the standard (RFC 6066 Sect. 4), the MFL extension
+ * only limits the maximum record payload size, so in theory
+ * we would be allowed to pack multiple records of payload size
+ * MFL into a single datagram. However, this would mean that there's
+ * no way to explicitly communicate MTU restrictions to the peer.
+ *
+ * The following reduction of max_len makes sure that we never
+ * write datagrams larger than MFL + Record Expansion Overhead.
+ */
+ if( max_len <= ssl->out_left )
+ return( 0 );
+
+ max_len -= ssl->out_left;
+#endif
+
+ ret = ssl_get_remaining_space_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+ remaining = (size_t) ret;
+
+ ret = mbedtls_ssl_get_record_expansion( ssl );
+ if( ret < 0 )
+ return( ret );
+ expansion = (size_t) ret;
+
+ if( remaining <= expansion )
+ return( 0 );
+
+ remaining -= expansion;
+ if( remaining >= max_len )
+ remaining = max_len;
+
+ return( (int) remaining );
+}
+
+/*
+ * Double the retransmit timeout value, within the allowed range,
+ * returning -1 if the maximum value has already been reached.
+ */
+static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
+{
+ uint32_t new_timeout;
+
+ if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
+ return( -1 );
+
+ /* Implement the final paragraph of RFC 6347 section 4.1.1.1
+ * in the following way: after the initial transmission and a first
+ * retransmission, back off to a temporary estimated MTU of 508 bytes.
+ * This value is guaranteed to be deliverable (if not guaranteed to be
+ * delivered) of any compliant IPv4 (and IPv6) network, and should work
+ * on most non-IP stacks too. */
+ if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
+ {
+ ssl->handshake->mtu = 508;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) );
+ }
+
+ new_timeout = 2 * ssl->handshake->retransmit_timeout;
+
+ /* Avoid arithmetic overflow and range overflow */
+ if( new_timeout < ssl->handshake->retransmit_timeout ||
+ new_timeout > ssl->conf->hs_timeout_max )
+ {
+ new_timeout = ssl->conf->hs_timeout_max;
+ }
+
+ ssl->handshake->retransmit_timeout = new_timeout;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs",
+ (unsigned long) ssl->handshake->retransmit_timeout ) );
+
+ return( 0 );
+}
+
+static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
+{
+ ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs",
+ (unsigned long) ssl->handshake->retransmit_timeout ) );
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
+ const unsigned char *key_enc, const unsigned char *key_dec,
+ size_t keylen,
+ const unsigned char *iv_enc, const unsigned char *iv_dec,
+ size_t ivlen,
+ const unsigned char *mac_enc, const unsigned char *mac_dec,
+ size_t maclen ) = NULL;
+int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
+int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+/*
+ * Encryption/decryption functions
+ */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+static size_t ssl_compute_padding_length( size_t len,
+ size_t granularity )
+{
+ return( ( granularity - ( len + 1 ) % granularity ) % granularity );
+}
+
+/* This functions transforms a (D)TLS plaintext fragment and a record content
+ * type into an instance of the (D)TLSInnerPlaintext structure. This is used
+ * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect
+ * a record's content type.
+ *
+ * struct {
+ * opaque content[DTLSPlaintext.length];
+ * ContentType real_type;
+ * uint8 zeros[length_of_padding];
+ * } (D)TLSInnerPlaintext;
+ *
+ * Input:
+ * - `content`: The beginning of the buffer holding the
+ * plaintext to be wrapped.
+ * - `*content_size`: The length of the plaintext in Bytes.
+ * - `max_len`: The number of Bytes available starting from
+ * `content`. This must be `>= *content_size`.
+ * - `rec_type`: The desired record content type.
+ *
+ * Output:
+ * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure.
+ * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure.
+ *
+ * Returns:
+ * - `0` on success.
+ * - A negative error code if `max_len` didn't offer enough space
+ * for the expansion.
+ */
+static int ssl_build_inner_plaintext( unsigned char *content,
+ size_t *content_size,
+ size_t remaining,
+ uint8_t rec_type,
+ size_t pad )
+{
+ size_t len = *content_size;
+
+ /* Write real content type */
+ if( remaining == 0 )
+ return( -1 );
+ content[ len ] = rec_type;
+ len++;
+ remaining--;
+
+ if( remaining < pad )
+ return( -1 );
+ memset( content + len, 0, pad );
+ len += pad;
+ remaining -= pad;
+
+ *content_size = len;
+ return( 0 );
+}
+
+/* This function parses a (D)TLSInnerPlaintext structure.
+ * See ssl_build_inner_plaintext() for details. */
+static int ssl_parse_inner_plaintext( unsigned char const *content,
+ size_t *content_size,
+ uint8_t *rec_type )
+{
+ size_t remaining = *content_size;
+
+ /* Determine length of padding by skipping zeroes from the back. */
+ do
+ {
+ if( remaining == 0 )
+ return( -1 );
+ remaining--;
+ } while( content[ remaining ] == 0 );
+
+ *content_size = remaining;
+ *rec_type = content[ remaining ];
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID ||
+ MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+/* `add_data` must have size 13 Bytes if the CID extension is disabled,
+ * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */
+static void ssl_extract_add_data_from_record( unsigned char* add_data,
+ size_t *add_data_len,
+ mbedtls_record *rec,
+ unsigned minor_ver )
+{
+ /* Quoting RFC 5246 (TLS 1.2):
+ *
+ * additional_data = seq_num + TLSCompressed.type +
+ * TLSCompressed.version + TLSCompressed.length;
+ *
+ * For the CID extension, this is extended as follows
+ * (quoting draft-ietf-tls-dtls-connection-id-05,
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05):
+ *
+ * additional_data = seq_num + DTLSPlaintext.type +
+ * DTLSPlaintext.version +
+ * cid +
+ * cid_length +
+ * length_of_DTLSInnerPlaintext;
+ *
+ * For TLS 1.3, the record sequence number is dropped from the AAD
+ * and encoded within the nonce of the AEAD operation instead.
+ */
+
+ unsigned char *cur = add_data;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 )
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+ {
+ ((void) minor_ver);
+ memcpy( cur, rec->ctr, sizeof( rec->ctr ) );
+ cur += sizeof( rec->ctr );
+ }
+
+ *cur = rec->type;
+ cur++;
+
+ memcpy( cur, rec->ver, sizeof( rec->ver ) );
+ cur += sizeof( rec->ver );
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( rec->cid_len != 0 )
+ {
+ memcpy( cur, rec->cid, rec->cid_len );
+ cur += rec->cid_len;
+
+ *cur = rec->cid_len;
+ cur++;
+
+ MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 );
+ cur += 2;
+ }
+ else
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ {
+ MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 );
+ cur += 2;
+ }
+
+ *add_data_len = cur - add_data;
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+
+#define SSL3_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */
+
+/*
+ * SSLv3.0 MAC functions
+ */
+static int ssl_mac( mbedtls_md_context_t *md_ctx,
+ const unsigned char *secret,
+ const unsigned char *buf, size_t len,
+ const unsigned char *ctr, int type,
+ unsigned char out[SSL3_MAC_MAX_BYTES] )
+{
+ unsigned char header[11];
+ unsigned char padding[48];
+ int padlen;
+ int md_size = mbedtls_md_get_size( md_ctx->md_info );
+ int md_type = mbedtls_md_get_type( md_ctx->md_info );
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* Only MD5 and SHA-1 supported */
+ if( md_type == MBEDTLS_MD_MD5 )
+ padlen = 48;
+ else
+ padlen = 40;
+
+ memcpy( header, ctr, 8 );
+ header[8] = (unsigned char) type;
+ MBEDTLS_PUT_UINT16_BE( len, header, 9);
+
+ memset( padding, 0x36, padlen );
+ ret = mbedtls_md_starts( md_ctx );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, secret, md_size );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, padding, padlen );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, header, 11 );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, buf, len );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_finish( md_ctx, out );
+ if( ret != 0 )
+ return( ret );
+
+ memset( padding, 0x5C, padlen );
+ ret = mbedtls_md_starts( md_ctx );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, secret, md_size );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, padding, padlen );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, out, md_size );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_finish( md_ctx, out );
+ if( ret != 0 )
+ return( ret );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_GCM_C) || \
+ defined(MBEDTLS_CCM_C) || \
+ defined(MBEDTLS_CHACHAPOLY_C)
+static int ssl_transform_aead_dynamic_iv_is_explicit(
+ mbedtls_ssl_transform const *transform )
+{
+ return( transform->ivlen != transform->fixed_ivlen );
+}
+
+/* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV )
+ *
+ * Concretely, this occurs in two variants:
+ *
+ * a) Fixed and dynamic IV lengths add up to total IV length, giving
+ * IV = fixed_iv || dynamic_iv
+ *
+ * This variant is used in TLS 1.2 when used with GCM or CCM.
+ *
+ * b) Fixed IV lengths matches total IV length, giving
+ * IV = fixed_iv XOR ( 0 || dynamic_iv )
+ *
+ * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly.
+ *
+ * See also the documentation of mbedtls_ssl_transform.
+ *
+ * This function has the precondition that
+ *
+ * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len )
+ *
+ * which has to be ensured by the caller. If this precondition
+ * violated, the behavior of this function is undefined.
+ */
+static void ssl_build_record_nonce( unsigned char *dst_iv,
+ size_t dst_iv_len,
+ unsigned char const *fixed_iv,
+ size_t fixed_iv_len,
+ unsigned char const *dynamic_iv,
+ size_t dynamic_iv_len )
+{
+ size_t i;
+
+ /* Start with Fixed IV || 0 */
+ memset( dst_iv, 0, dst_iv_len );
+ memcpy( dst_iv, fixed_iv, fixed_iv_len );
+
+ dst_iv += dst_iv_len - dynamic_iv_len;
+ for( i = 0; i < dynamic_iv_len; i++ )
+ dst_iv[i] ^= dynamic_iv[i];
+}
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
+
+int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform,
+ mbedtls_record *rec,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ mbedtls_cipher_mode_t mode;
+ int auth_done = 0;
+ unsigned char * data;
+ unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ];
+ size_t add_data_len;
+ size_t post_avail;
+
+ /* The SSL context is only used for debugging purposes! */
+#if !defined(MBEDTLS_DEBUG_C)
+ ssl = NULL; /* make sure we don't use it except for debug */
+ ((void) ssl);
+#endif
+
+ /* The PRNG is used for dynamic IV generation that's used
+ * for CBC transformations in TLS 1.1 and TLS 1.2. */
+#if !( defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
+ ( defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) ) )
+ ((void) f_rng);
+ ((void) p_rng);
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
+
+ if( transform == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ if( rec == NULL
+ || rec->buf == NULL
+ || rec->buf_len < rec->data_offset
+ || rec->buf_len - rec->data_offset < rec->data_len
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ || rec->cid_len != 0
+#endif
+ )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ data = rec->buf + rec->data_offset;
+ post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
+ data, rec->data_len );
+
+ mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc );
+
+ if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %" MBEDTLS_PRINTF_SIZET
+ " too large, maximum %" MBEDTLS_PRINTF_SIZET,
+ rec->data_len,
+ (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ /* The following two code paths implement the (D)TLSInnerPlaintext
+ * structure present in TLS 1.3 and DTLS 1.2 + CID.
+ *
+ * See ssl_build_inner_plaintext() for more information.
+ *
+ * Note that this changes `rec->data_len`, and hence
+ * `post_avail` needs to be recalculated afterwards.
+ *
+ * Note also that the two code paths cannot occur simultaneously
+ * since they apply to different versions of the protocol. There
+ * is hence no risk of double-addition of the inner plaintext.
+ */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+ {
+ size_t padding =
+ ssl_compute_padding_length( rec->data_len,
+ MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY );
+ if( ssl_build_inner_plaintext( data,
+ &rec->data_len,
+ post_avail,
+ rec->type,
+ padding ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA;
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /*
+ * Add CID information
+ */
+ rec->cid_len = transform->out_cid_len;
+ memcpy( rec->cid, transform->out_cid, transform->out_cid_len );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len );
+
+ if( rec->cid_len != 0 )
+ {
+ size_t padding =
+ ssl_compute_padding_length( rec->data_len,
+ MBEDTLS_SSL_CID_PADDING_GRANULARITY );
+ /*
+ * Wrap plaintext into DTLSInnerPlaintext structure.
+ * See ssl_build_inner_plaintext() for more information.
+ *
+ * Note that this changes `rec->data_len`, and hence
+ * `post_avail` needs to be recalculated afterwards.
+ */
+ if( ssl_build_inner_plaintext( data,
+ &rec->data_len,
+ post_avail,
+ rec->type,
+ padding ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ rec->type = MBEDTLS_SSL_MSG_CID;
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
+
+ /*
+ * Add MAC before if needed
+ */
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ if( mode == MBEDTLS_MODE_STREAM ||
+ ( mode == MBEDTLS_MODE_CBC
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
+#endif
+ ) )
+ {
+ if( post_avail < transform->maclen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ unsigned char mac[SSL3_MAC_MAX_BYTES];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ ret = ssl_mac( &transform->md_ctx_enc, transform->mac_enc,
+ data, rec->data_len, rec->ctr, rec->type, mac );
+ if( ret == 0 )
+ memcpy( data + rec->data_len, mac, transform->maclen );
+ mbedtls_platform_zeroize( mac, transform->maclen );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
+ return( ret );
+ }
+ }
+ else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+ {
+ unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+ add_data, add_data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_disabled;
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+ data, rec->data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_disabled;
+ ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
+ if( ret != 0 )
+ goto hmac_failed_etm_disabled;
+ ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
+ if( ret != 0 )
+ goto hmac_failed_etm_disabled;
+
+ memcpy( data + rec->data_len, mac, transform->maclen );
+
+ hmac_failed_etm_disabled:
+ mbedtls_platform_zeroize( mac, transform->maclen );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
+ return( ret );
+ }
+ }
+ else
+#endif
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len,
+ transform->maclen );
+
+ rec->data_len += transform->maclen;
+ post_avail -= transform->maclen;
+ auth_done++;
+ }
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+
+ /*
+ * Encrypt
+ */
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
+ if( mode == MBEDTLS_MODE_STREAM )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t olen;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
+ "including %d bytes of padding",
+ rec->data_len, 0 ) );
+
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
+ transform->iv_enc, transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+
+ if( rec->data_len != olen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+ else
+#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
+
+#if defined(MBEDTLS_GCM_C) || \
+ defined(MBEDTLS_CCM_C) || \
+ defined(MBEDTLS_CHACHAPOLY_C)
+ if( mode == MBEDTLS_MODE_GCM ||
+ mode == MBEDTLS_MODE_CCM ||
+ mode == MBEDTLS_MODE_CHACHAPOLY )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char iv[12];
+ unsigned char *dynamic_iv;
+ size_t dynamic_iv_len;
+ int dynamic_iv_is_explicit =
+ ssl_transform_aead_dynamic_iv_is_explicit( transform );
+
+ /* Check that there's space for the authentication tag. */
+ if( post_avail < transform->taglen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ /*
+ * Build nonce for AEAD encryption.
+ *
+ * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
+ * part of the IV is prepended to the ciphertext and
+ * can be chosen freely - in particular, it need not
+ * agree with the record sequence number.
+ * However, since ChaChaPoly as well as all AEAD modes
+ * in TLS 1.3 use the record sequence number as the
+ * dynamic part of the nonce, we uniformly use the
+ * record sequence number here in all cases.
+ */
+ dynamic_iv = rec->ctr;
+ dynamic_iv_len = sizeof( rec->ctr );
+
+ ssl_build_record_nonce( iv, sizeof( iv ),
+ transform->iv_enc,
+ transform->fixed_ivlen,
+ dynamic_iv,
+ dynamic_iv_len );
+
+ /*
+ * Build additional data for AEAD encryption.
+ * This depends on the TLS version.
+ */
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
+ iv, transform->ivlen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)",
+ dynamic_iv,
+ dynamic_iv_is_explicit ? dynamic_iv_len : 0 );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
+ add_data, add_data_len );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
+ "including 0 bytes of padding",
+ rec->data_len ) );
+
+ /*
+ * Encrypt and authenticate
+ */
+
+ if( ( ret = mbedtls_cipher_auth_encrypt_ext( &transform->cipher_ctx_enc,
+ iv, transform->ivlen,
+ add_data, add_data_len,
+ data, rec->data_len, /* src */
+ data, rec->buf_len - (data - rec->buf), /* dst */
+ &rec->data_len,
+ transform->taglen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
+ return( ret );
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag",
+ data + rec->data_len - transform->taglen,
+ transform->taglen );
+ /* Account for authentication tag. */
+ post_avail -= transform->taglen;
+
+ /*
+ * Prefix record content with dynamic IV in case it is explicit.
+ */
+ if( dynamic_iv_is_explicit != 0 )
+ {
+ if( rec->data_offset < dynamic_iv_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ memcpy( data - dynamic_iv_len, dynamic_iv, dynamic_iv_len );
+ rec->data_offset -= dynamic_iv_len;
+ rec->data_len += dynamic_iv_len;
+ }
+
+ auth_done++;
+ }
+ else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
+ if( mode == MBEDTLS_MODE_CBC )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t padlen, i;
+ size_t olen;
+
+ /* Currently we're always using minimal padding
+ * (up to 255 bytes would be allowed). */
+ padlen = transform->ivlen - ( rec->data_len + 1 ) % transform->ivlen;
+ if( padlen == transform->ivlen )
+ padlen = 0;
+
+ /* Check there's enough space in the buffer for the padding. */
+ if( post_avail < padlen + 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ for( i = 0; i <= padlen; i++ )
+ data[rec->data_len + i] = (unsigned char) padlen;
+
+ rec->data_len += padlen + 1;
+ post_avail -= padlen + 1;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ /*
+ * Prepend per-record IV for block cipher in TLS v1.1 and up as per
+ * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
+ */
+ if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ if( f_rng == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ if( rec->data_offset < transform->ivlen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ /*
+ * Generate IV
+ */
+ ret = f_rng( p_rng, transform->iv_enc, transform->ivlen );
+ if( ret != 0 )
+ return( ret );
+
+ memcpy( data - transform->ivlen, transform->iv_enc,
+ transform->ivlen );
+
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
+ "including %" MBEDTLS_PRINTF_SIZET
+ " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding",
+ rec->data_len, transform->ivlen,
+ padlen + 1 ) );
+
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
+ transform->iv_enc,
+ transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+
+ if( rec->data_len != olen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
+ if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ /*
+ * Save IV in SSL3 and TLS1
+ */
+ memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv,
+ transform->ivlen );
+ }
+ else
+#endif
+ {
+ data -= transform->ivlen;
+ rec->data_offset -= transform->ivlen;
+ rec->data_len += transform->ivlen;
+ }
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ if( auth_done == 0 )
+ {
+ unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+
+ /*
+ * MAC(MAC_write_key, seq_num +
+ * TLSCipherText.type +
+ * TLSCipherText.version +
+ * length_of( (IV +) ENC(...) ) +
+ * IV + // except for TLS 1.0
+ * ENC(content + padding + padding_length));
+ */
+
+ if( post_avail < transform->maclen)
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ ssl_extract_add_data_from_record( add_data, &add_data_len,
+ rec, transform->minor_ver );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
+ add_data_len );
+
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
+ add_data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+ data, rec->data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+
+ memcpy( data + rec->data_len, mac, transform->maclen );
+
+ rec->data_len += transform->maclen;
+ post_avail -= transform->maclen;
+ auth_done++;
+
+ hmac_failed_etm_enabled:
+ mbedtls_platform_zeroize( mac, transform->maclen );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
+ return( ret );
+ }
+ }
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+ }
+ else
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* Make extra sure authentication was performed, exactly once */
+ if( auth_done != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
+
+ return( 0 );
+}
+
+int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
+ mbedtls_ssl_transform *transform,
+ mbedtls_record *rec )
+{
+ size_t olen;
+ mbedtls_cipher_mode_t mode;
+ int ret, auth_done = 0;
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ size_t padlen = 0, correct = 1;
+#endif
+ unsigned char* data;
+ unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ];
+ size_t add_data_len;
+
+#if !defined(MBEDTLS_DEBUG_C)
+ ssl = NULL; /* make sure we don't use it except for debug */
+ ((void) ssl);
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
+ if( rec == NULL ||
+ rec->buf == NULL ||
+ rec->buf_len < rec->data_offset ||
+ rec->buf_len - rec->data_offset < rec->data_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to decrypt_buf" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ data = rec->buf + rec->data_offset;
+ mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec );
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /*
+ * Match record's CID with incoming CID.
+ */
+ if( rec->cid_len != transform->in_cid_len ||
+ memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_CID );
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
+ if( mode == MBEDTLS_MODE_STREAM )
+ {
+ padlen = 0;
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
+ transform->iv_dec,
+ transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+
+ if( rec->data_len != olen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+ else
+#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
+#if defined(MBEDTLS_GCM_C) || \
+ defined(MBEDTLS_CCM_C) || \
+ defined(MBEDTLS_CHACHAPOLY_C)
+ if( mode == MBEDTLS_MODE_GCM ||
+ mode == MBEDTLS_MODE_CCM ||
+ mode == MBEDTLS_MODE_CHACHAPOLY )
+ {
+ unsigned char iv[12];
+ unsigned char *dynamic_iv;
+ size_t dynamic_iv_len;
+
+ /*
+ * Extract dynamic part of nonce for AEAD decryption.
+ *
+ * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
+ * part of the IV is prepended to the ciphertext and
+ * can be chosen freely - in particular, it need not
+ * agree with the record sequence number.
+ */
+ dynamic_iv_len = sizeof( rec->ctr );
+ if( ssl_transform_aead_dynamic_iv_is_explicit( transform ) == 1 )
+ {
+ if( rec->data_len < dynamic_iv_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ",
+ rec->data_len,
+ dynamic_iv_len ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+ dynamic_iv = data;
+
+ data += dynamic_iv_len;
+ rec->data_offset += dynamic_iv_len;
+ rec->data_len -= dynamic_iv_len;
+ }
+ else
+ {
+ dynamic_iv = rec->ctr;
+ }
+
+ /* Check that there's space for the authentication tag. */
+ if( rec->data_len < transform->taglen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ",
+ rec->data_len,
+ transform->taglen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+ rec->data_len -= transform->taglen;
+
+ /*
+ * Prepare nonce from dynamic and static parts.
+ */
+ ssl_build_record_nonce( iv, sizeof( iv ),
+ transform->iv_dec,
+ transform->fixed_ivlen,
+ dynamic_iv,
+ dynamic_iv_len );
+
+ /*
+ * Build additional data for AEAD encryption.
+ * This depends on the TLS version.
+ */
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
+ add_data, add_data_len );
+
+ /* Because of the check above, we know that there are
+ * explicit_iv_len Bytes preceeding data, and taglen
+ * bytes following data + data_len. This justifies
+ * the debug message and the invocation of
+ * mbedtls_cipher_auth_decrypt() below. */
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", data + rec->data_len,
+ transform->taglen );
+
+ /*
+ * Decrypt and authenticate
+ */
+ if( ( ret = mbedtls_cipher_auth_decrypt_ext( &transform->cipher_ctx_dec,
+ iv, transform->ivlen,
+ add_data, add_data_len,
+ data, rec->data_len + transform->taglen, /* src */
+ data, rec->buf_len - (data - rec->buf), &olen, /* dst */
+ transform->taglen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
+
+ if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+
+ return( ret );
+ }
+ auth_done++;
+
+ /* Double-check that AEAD decryption doesn't change content length. */
+ if( olen != rec->data_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+ else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
+ if( mode == MBEDTLS_MODE_CBC )
+ {
+ size_t minlen = 0;
+
+ /*
+ * Check immediate ciphertext sanity
+ */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ /* The ciphertext is prefixed with the CBC IV. */
+ minlen += transform->ivlen;
+ }
+#endif
+
+ /* Size considerations:
+ *
+ * - The CBC cipher text must not be empty and hence
+ * at least of size transform->ivlen.
+ *
+ * Together with the potential IV-prefix, this explains
+ * the first of the two checks below.
+ *
+ * - The record must contain a MAC, either in plain or
+ * encrypted, depending on whether Encrypt-then-MAC
+ * is used or not.
+ * - If it is, the message contains the IV-prefix,
+ * the CBC ciphertext, and the MAC.
+ * - If it is not, the padded plaintext, and hence
+ * the CBC ciphertext, has at least length maclen + 1
+ * because there is at least the padding length byte.
+ *
+ * As the CBC ciphertext is not empty, both cases give the
+ * lower bound minlen + maclen + 1 on the record size, which
+ * we test for in the second check below.
+ */
+ if( rec->data_len < minlen + transform->ivlen ||
+ rec->data_len < minlen + transform->maclen + 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET
+ "), maclen (%" MBEDTLS_PRINTF_SIZET ") "
+ "+ 1 ) ( + expl IV )", rec->data_len,
+ transform->ivlen,
+ transform->maclen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+
+ /*
+ * Authenticate before decrypt if enabled
+ */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
+ {
+ unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
+
+ /* Update data_len in tandem with add_data.
+ *
+ * The subtraction is safe because of the previous check
+ * data_len >= minlen + maclen + 1.
+ *
+ * Afterwards, we know that data + data_len is followed by at
+ * least maclen Bytes, which justifies the call to
+ * mbedtls_ct_memcmp() below.
+ *
+ * Further, we still know that data_len > minlen */
+ rec->data_len -= transform->maclen;
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+
+ /* Calculate expected MAC. */
+ MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
+ add_data_len );
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
+ add_data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_dec,
+ data, rec->data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_reset( &transform->md_ctx_dec );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len,
+ transform->maclen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
+ transform->maclen );
+
+ /* Compare expected MAC with MAC at the end of the record. */
+ if( mbedtls_ct_memcmp( data + rec->data_len, mac_expect,
+ transform->maclen ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
+ ret = MBEDTLS_ERR_SSL_INVALID_MAC;
+ goto hmac_failed_etm_enabled;
+ }
+ auth_done++;
+
+ hmac_failed_etm_enabled:
+ mbedtls_platform_zeroize( mac_expect, transform->maclen );
+ if( ret != 0 )
+ {
+ if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret );
+ return( ret );
+ }
+ }
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+ /*
+ * Check length sanity
+ */
+
+ /* We know from above that data_len > minlen >= 0,
+ * so the following check in particular implies that
+ * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */
+ if( rec->data_len % transform->ivlen != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0",
+ rec->data_len, transform->ivlen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ /*
+ * Initialize for prepended IV for block cipher in TLS v1.1 and up
+ */
+ if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
+ memcpy( transform->iv_dec, data, transform->ivlen );
+
+ data += transform->ivlen;
+ rec->data_offset += transform->ivlen;
+ rec->data_len -= transform->ivlen;
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
+
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
+ transform->iv_dec, transform->ivlen,
+ data, rec->data_len, data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+
+ /* Double-check that length hasn't changed during decryption. */
+ if( rec->data_len != olen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
+ if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ /*
+ * Save IV in SSL3 and TLS1, where CBC decryption of consecutive
+ * records is equivalent to CBC decryption of the concatenation
+ * of the records; in other words, IVs are maintained across
+ * record decryptions.
+ */
+ memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv,
+ transform->ivlen );
+ }
+#endif
+
+ /* Safe since data_len >= minlen + maclen + 1, so after having
+ * subtracted at most minlen and maclen up to this point,
+ * data_len > 0 (because of data_len % ivlen == 0, it's actually
+ * >= ivlen ). */
+ padlen = data[rec->data_len - 1];
+
+ if( auth_done == 1 )
+ {
+ const size_t mask = mbedtls_ct_size_mask_ge(
+ rec->data_len,
+ padlen + 1 );
+ correct &= mask;
+ padlen &= mask;
+ }
+ else
+ {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ if( rec->data_len < transform->maclen + padlen + 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ ") < maclen (%" MBEDTLS_PRINTF_SIZET
+ ") + padlen (%" MBEDTLS_PRINTF_SIZET ")",
+ rec->data_len,
+ transform->maclen,
+ padlen + 1 ) );
+ }
+#endif
+
+ const size_t mask = mbedtls_ct_size_mask_ge(
+ rec->data_len,
+ transform->maclen + padlen + 1 );
+ correct &= mask;
+ padlen &= mask;
+ }
+
+ padlen++;
+
+ /* Regardless of the validity of the padding,
+ * we have data_len >= padlen here. */
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ /* This is the SSL 3.0 path, we don't have to worry about Lucky
+ * 13, because there's a strictly worse padding attack built in
+ * the protocol (known as part of POODLE), so we don't care if the
+ * code is not constant-time, in particular branches are OK. */
+ if( padlen > transform->ivlen )
+ {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %" MBEDTLS_PRINTF_SIZET ", "
+ "should be no more than %" MBEDTLS_PRINTF_SIZET,
+ padlen, transform->ivlen ) );
+#endif
+ correct = 0;
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ /* The padding check involves a series of up to 256
+ * consecutive memory reads at the end of the record
+ * plaintext buffer. In order to hide the length and
+ * validity of the padding, always perform exactly
+ * `min(256,plaintext_len)` reads (but take into account
+ * only the last `padlen` bytes for the padding check). */
+ size_t pad_count = 0;
+ volatile unsigned char* const check = data;
+
+ /* Index of first padding byte; it has been ensured above
+ * that the subtraction is safe. */
+ size_t const padding_idx = rec->data_len - padlen;
+ size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
+ size_t const start_idx = rec->data_len - num_checks;
+ size_t idx;
+
+ for( idx = start_idx; idx < rec->data_len; idx++ )
+ {
+ /* pad_count += (idx >= padding_idx) &&
+ * (check[idx] == padlen - 1);
+ */
+ const size_t mask = mbedtls_ct_size_mask_ge( idx, padding_idx );
+ const size_t equal = mbedtls_ct_size_bool_eq( check[idx],
+ padlen - 1 );
+ pad_count += mask & equal;
+ }
+ correct &= mbedtls_ct_size_bool_eq( pad_count, padlen );
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ if( padlen > 0 && correct == 0 )
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
+#endif
+ padlen &= mbedtls_ct_size_mask( correct );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+ MBEDTLS_SSL_PROTO_TLS1_2 */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* If the padding was found to be invalid, padlen == 0
+ * and the subtraction is safe. If the padding was found valid,
+ * padlen hasn't been changed and the previous assertion
+ * data_len >= padlen still holds. */
+ rec->data_len -= padlen;
+ }
+ else
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
+ data, rec->data_len );
+#endif
+
+ /*
+ * Authenticate if not done yet.
+ * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
+ */
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ if( auth_done == 0 )
+ {
+ unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
+ unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
+
+ /* If the initial value of padlen was such that
+ * data_len < maclen + padlen + 1, then padlen
+ * got reset to 1, and the initial check
+ * data_len >= minlen + maclen + 1
+ * guarantees that at this point we still
+ * have at least data_len >= maclen.
+ *
+ * If the initial value of padlen was such that
+ * data_len >= maclen + padlen + 1, then we have
+ * subtracted either padlen + 1 (if the padding was correct)
+ * or 0 (if the padding was incorrect) since then,
+ * hence data_len >= maclen in any case.
+ */
+ rec->data_len -= transform->maclen;
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ ret = ssl_mac( &transform->md_ctx_dec,
+ transform->mac_dec,
+ data, rec->data_len,
+ rec->ctr, rec->type,
+ mac_expect );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
+ goto hmac_failed_etm_disabled;
+ }
+ memcpy( mac_peer, data + rec->data_len, transform->maclen );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ /*
+ * The next two sizes are the minimum and maximum values of
+ * data_len over all padlen values.
+ *
+ * They're independent of padlen, since we previously did
+ * data_len -= padlen.
+ *
+ * Note that max_len + maclen is never more than the buffer
+ * length, as we previously did in_msglen -= maclen too.
+ */
+ const size_t max_len = rec->data_len + padlen;
+ const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
+
+ ret = mbedtls_ct_hmac( &transform->md_ctx_dec,
+ add_data, add_data_len,
+ data, rec->data_len, min_len, max_len,
+ mac_expect );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret );
+ goto hmac_failed_etm_disabled;
+ }
+
+ mbedtls_ct_memcpy_offset( mac_peer, data,
+ rec->data_len,
+ min_len, max_len,
+ transform->maclen );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+ MBEDTLS_SSL_PROTO_TLS1_2 */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, transform->maclen );
+#endif
+
+ if( mbedtls_ct_memcmp( mac_peer, mac_expect,
+ transform->maclen ) != 0 )
+ {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
+#endif
+ correct = 0;
+ }
+ auth_done++;
+
+ hmac_failed_etm_disabled:
+ mbedtls_platform_zeroize( mac_peer, transform->maclen );
+ mbedtls_platform_zeroize( mac_expect, transform->maclen );
+ if( ret != 0 )
+ return( ret );
+ }
+
+ /*
+ * Finally check the correct flag
+ */
+ if( correct == 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+
+ /* Make extra sure authentication was performed, exactly once */
+ if( auth_done != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+ {
+ /* Remove inner padding and infer true content type. */
+ ret = ssl_parse_inner_plaintext( data, &rec->data_len,
+ &rec->type );
+
+ if( ret != 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( rec->cid_len != 0 )
+ {
+ ret = ssl_parse_inner_plaintext( data, &rec->data_len,
+ &rec->type );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
+
+ return( 0 );
+}
+
+#undef MAC_NONE
+#undef MAC_PLAINTEXT
+#undef MAC_CIPHERTEXT
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+/*
+ * Compression/decompression functions
+ */
+static int ssl_compress_buf( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *msg_post = ssl->out_msg;
+ ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
+ size_t len_pre = ssl->out_msglen;
+ unsigned char *msg_pre = ssl->compress_buf;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
+
+ if( len_pre == 0 )
+ return( 0 );
+
+ memcpy( msg_pre, ssl->out_msg, len_pre );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
+ ssl->out_msglen ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
+ ssl->out_msg, ssl->out_msglen );
+
+ ssl->transform_out->ctx_deflate.next_in = msg_pre;
+ ssl->transform_out->ctx_deflate.avail_in = len_pre;
+ ssl->transform_out->ctx_deflate.next_out = msg_post;
+ ssl->transform_out->ctx_deflate.avail_out = out_buf_len - bytes_written;
+
+ ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
+ if( ret != Z_OK )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
+ return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+ }
+
+ ssl->out_msglen = out_buf_len -
+ ssl->transform_out->ctx_deflate.avail_out - bytes_written;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
+ ssl->out_msglen ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
+ ssl->out_msg, ssl->out_msglen );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
+
+ return( 0 );
+}
+
+static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *msg_post = ssl->in_msg;
+ ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
+ size_t len_pre = ssl->in_msglen;
+ unsigned char *msg_pre = ssl->compress_buf;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
+
+ if( len_pre == 0 )
+ return( 0 );
+
+ memcpy( msg_pre, ssl->in_msg, len_pre );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
+ ssl->in_msglen ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
+ ssl->in_msg, ssl->in_msglen );
+
+ ssl->transform_in->ctx_inflate.next_in = msg_pre;
+ ssl->transform_in->ctx_inflate.avail_in = len_pre;
+ ssl->transform_in->ctx_inflate.next_out = msg_post;
+ ssl->transform_in->ctx_inflate.avail_out = in_buf_len - header_bytes;
+
+ ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
+ if( ret != Z_OK )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
+ return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+ }
+
+ ssl->in_msglen = in_buf_len -
+ ssl->transform_in->ctx_inflate.avail_out - header_bytes;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
+ ssl->in_msglen ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
+ ssl->in_msg, ssl->in_msglen );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+
+/*
+ * Fill the input message buffer by appending data to it.
+ * The amount of data already fetched is in ssl->in_left.
+ *
+ * If we return 0, is it guaranteed that (at least) nb_want bytes are
+ * available (from this read and/or a previous one). Otherwise, an error code
+ * is returned (possibly EOF or WANT_READ).
+ *
+ * With stream transport (TLS) on success ssl->in_left == nb_want, but
+ * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
+ * since we always read a whole datagram at once.
+ *
+ * For DTLS, it is up to the caller to set ssl->next_record_offset when
+ * they're done reading a record.
+ */
+int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
+
+ if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
+ "or mbedtls_ssl_set_bio()" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ uint32_t timeout;
+
+ /*
+ * The point is, we need to always read a full datagram at once, so we
+ * sometimes read more then requested, and handle the additional data.
+ * It could be the rest of the current record (while fetching the
+ * header) and/or some other records in the same datagram.
+ */
+
+ /*
+ * Move to the next record in the already read datagram if applicable
+ */
+ if( ssl->next_record_offset != 0 )
+ {
+ if( ssl->in_left < ssl->next_record_offset )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ ssl->in_left -= ssl->next_record_offset;
+
+ if( ssl->in_left != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %"
+ MBEDTLS_PRINTF_SIZET,
+ ssl->next_record_offset ) );
+ memmove( ssl->in_hdr,
+ ssl->in_hdr + ssl->next_record_offset,
+ ssl->in_left );
+ }
+
+ ssl->next_record_offset = 0;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
+ ", nb_want: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_left, nb_want ) );
+
+ /*
+ * Done if we already have enough data.
+ */
+ if( nb_want <= ssl->in_left)
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
+ return( 0 );
+ }
+
+ /*
+ * A record can't be split across datagrams. If we need to read but
+ * are not at the beginning of a new record, the caller did something
+ * wrong.
+ */
+ if( ssl->in_left != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /*
+ * Don't even try to read if time's out already.
+ * This avoids by-passing the timer when repeatedly receiving messages
+ * that will end up being dropped.
+ */
+ if( mbedtls_ssl_check_timer( ssl ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) );
+ ret = MBEDTLS_ERR_SSL_TIMEOUT;
+ }
+ else
+ {
+ len = in_buf_len - ( ssl->in_hdr - ssl->in_buf );
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ timeout = ssl->handshake->retransmit_timeout;
+ else
+ timeout = ssl->conf->read_timeout;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %lu ms", (unsigned long) timeout ) );
+
+ if( ssl->f_recv_timeout != NULL )
+ ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
+ timeout );
+ else
+ ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
+
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
+
+ if( ret == 0 )
+ return( MBEDTLS_ERR_SSL_CONN_EOF );
+ }
+
+ if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
+ mbedtls_ssl_set_timer( ssl, 0 );
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ if( ssl_double_retransmit_timeout( ssl ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
+ return( MBEDTLS_ERR_SSL_TIMEOUT );
+ }
+
+ if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
+ return( ret );
+ }
+
+ return( MBEDTLS_ERR_SSL_WANT_READ );
+ }
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+ else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+ {
+ if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request",
+ ret );
+ return( ret );
+ }
+
+ return( MBEDTLS_ERR_SSL_WANT_READ );
+ }
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
+ }
+
+ if( ret < 0 )
+ return( ret );
+
+ ssl->in_left = ret;
+ }
+ else
+#endif
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
+ ", nb_want: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_left, nb_want ) );
+
+ while( ssl->in_left < nb_want )
+ {
+ len = nb_want - ssl->in_left;
+
+ if( mbedtls_ssl_check_timer( ssl ) != 0 )
+ ret = MBEDTLS_ERR_SSL_TIMEOUT;
+ else
+ {
+ if( ssl->f_recv_timeout != NULL )
+ {
+ ret = ssl->f_recv_timeout( ssl->p_bio,
+ ssl->in_hdr + ssl->in_left, len,
+ ssl->conf->read_timeout );
+ }
+ else
+ {
+ ret = ssl->f_recv( ssl->p_bio,
+ ssl->in_hdr + ssl->in_left, len );
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
+ ", nb_want: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_left, nb_want ) );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
+
+ if( ret == 0 )
+ return( MBEDTLS_ERR_SSL_CONN_EOF );
+
+ if( ret < 0 )
+ return( ret );
+
+ if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET " were requested",
+ ret, len ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ ssl->in_left += ret;
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
+
+ return( 0 );
+}
+
+/*
+ * Flush any data not yet written
+ */
+int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *buf;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
+
+ if( ssl->f_send == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
+ "or mbedtls_ssl_set_bio()" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ /* Avoid incrementing counter if data is flushed */
+ if( ssl->out_left == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
+ return( 0 );
+ }
+
+ while( ssl->out_left > 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %" MBEDTLS_PRINTF_SIZET
+ ", out_left: %" MBEDTLS_PRINTF_SIZET,
+ mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
+
+ buf = ssl->out_hdr - ssl->out_left;
+ ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
+
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
+
+ if( ret <= 0 )
+ return( ret );
+
+ if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET " bytes were sent",
+ ret, ssl->out_left ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ ssl->out_left -= ret;
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->out_hdr = ssl->out_buf;
+ }
+ else
+#endif
+ {
+ ssl->out_hdr = ssl->out_buf + 8;
+ }
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
+
+ return( 0 );
+}
+
+/*
+ * Functions to handle the DTLS retransmission state machine
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+/*
+ * Append current handshake message to current outgoing flight
+ */
+static int ssl_flight_append( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_flight_item *msg;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
+ ssl->out_msg, ssl->out_msglen );
+
+ /* Allocate space for current message */
+ if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
+ sizeof( mbedtls_ssl_flight_item ) ) );
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
+
+ if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
+ ssl->out_msglen ) );
+ mbedtls_free( msg );
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
+
+ /* Copy current handshake message with headers */
+ memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
+ msg->len = ssl->out_msglen;
+ msg->type = ssl->out_msgtype;
+ msg->next = NULL;
+
+ /* Append to the current flight */
+ if( ssl->handshake->flight == NULL )
+ ssl->handshake->flight = msg;
+ else
+ {
+ mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
+ while( cur->next != NULL )
+ cur = cur->next;
+ cur->next = msg;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
+ return( 0 );
+}
+
+/*
+ * Free the current flight of handshake messages
+ */
+void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight )
+{
+ mbedtls_ssl_flight_item *cur = flight;
+ mbedtls_ssl_flight_item *next;
+
+ while( cur != NULL )
+ {
+ next = cur->next;
+
+ mbedtls_free( cur->p );
+ mbedtls_free( cur );
+
+ cur = next;
+ }
+}
+
+/*
+ * Swap transform_out and out_ctr with the alternative ones
+ */
+static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_transform *tmp_transform;
+ unsigned char tmp_out_ctr[8];
+
+ if( ssl->transform_out == ssl->handshake->alt_transform_out )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
+ return( 0 );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
+
+ /* Swap transforms */
+ tmp_transform = ssl->transform_out;
+ ssl->transform_out = ssl->handshake->alt_transform_out;
+ ssl->handshake->alt_transform_out = tmp_transform;
+
+ /* Swap epoch + sequence_number */
+ memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
+ memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
+ memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
+
+ /* Adjust to the newly activated transform */
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ if( mbedtls_ssl_hw_record_activate != NULL )
+ {
+ int ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+ }
+#endif
+
+ return( 0 );
+}
+
+/*
+ * Retransmit the current flight of messages.
+ */
+int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
+{
+ int ret = 0;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
+
+ ret = mbedtls_ssl_flight_transmit( ssl );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
+
+ return( ret );
+}
+
+/*
+ * Transmit or retransmit the current flight of messages.
+ *
+ * Need to remember the current message in case flush_output returns
+ * WANT_WRITE, causing us to exit this function and come back later.
+ * This function must be called until state is no longer SENDING.
+ */
+int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
+
+ if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) );
+
+ ssl->handshake->cur_msg = ssl->handshake->flight;
+ ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
+ ret = ssl_swap_epochs( ssl );
+ if( ret != 0 )
+ return( ret );
+
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
+ }
+
+ while( ssl->handshake->cur_msg != NULL )
+ {
+ size_t max_frag_len;
+ const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
+
+ int const is_finished =
+ ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
+
+ uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
+ SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
+
+ /* Swap epochs before sending Finished: we can't do it after
+ * sending ChangeCipherSpec, in case write returns WANT_READ.
+ * Must be done before copying, may change out_msg pointer */
+ if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
+ ret = ssl_swap_epochs( ssl );
+ if( ret != 0 )
+ return( ret );
+ }
+
+ ret = ssl_get_remaining_payload_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+ max_frag_len = (size_t) ret;
+
+ /* CCS is copied as is, while HS messages may need fragmentation */
+ if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ if( max_frag_len == 0 )
+ {
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ continue;
+ }
+
+ memcpy( ssl->out_msg, cur->p, cur->len );
+ ssl->out_msglen = cur->len;
+ ssl->out_msgtype = cur->type;
+
+ /* Update position inside current message */
+ ssl->handshake->cur_msg_p += cur->len;
+ }
+ else
+ {
+ const unsigned char * const p = ssl->handshake->cur_msg_p;
+ const size_t hs_len = cur->len - 12;
+ const size_t frag_off = p - ( cur->p + 12 );
+ const size_t rem_len = hs_len - frag_off;
+ size_t cur_hs_frag_len, max_hs_frag_len;
+
+ if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
+ {
+ if( is_finished )
+ {
+ ret = ssl_swap_epochs( ssl );
+ if( ret != 0 )
+ return( ret );
+ }
+
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ continue;
+ }
+ max_hs_frag_len = max_frag_len - 12;
+
+ cur_hs_frag_len = rem_len > max_hs_frag_len ?
+ max_hs_frag_len : rem_len;
+
+ if( frag_off == 0 && cur_hs_frag_len != hs_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
+ (unsigned) cur_hs_frag_len,
+ (unsigned) max_hs_frag_len ) );
+ }
+
+ /* Messages are stored with handshake headers as if not fragmented,
+ * copy beginning of headers then fill fragmentation fields.
+ * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
+ memcpy( ssl->out_msg, cur->p, 6 );
+
+ ssl->out_msg[6] = MBEDTLS_BYTE_2( frag_off );
+ ssl->out_msg[7] = MBEDTLS_BYTE_1( frag_off );
+ ssl->out_msg[8] = MBEDTLS_BYTE_0( frag_off );
+
+ ssl->out_msg[ 9] = MBEDTLS_BYTE_2( cur_hs_frag_len );
+ ssl->out_msg[10] = MBEDTLS_BYTE_1( cur_hs_frag_len );
+ ssl->out_msg[11] = MBEDTLS_BYTE_0( cur_hs_frag_len );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
+
+ /* Copy the handshake message content and set records fields */
+ memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
+ ssl->out_msglen = cur_hs_frag_len + 12;
+ ssl->out_msgtype = cur->type;
+
+ /* Update position inside current message */
+ ssl->handshake->cur_msg_p += cur_hs_frag_len;
+ }
+
+ /* If done with the current message move to the next one if any */
+ if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
+ {
+ if( cur->next != NULL )
+ {
+ ssl->handshake->cur_msg = cur->next;
+ ssl->handshake->cur_msg_p = cur->next->p + 12;
+ }
+ else
+ {
+ ssl->handshake->cur_msg = NULL;
+ ssl->handshake->cur_msg_p = NULL;
+ }
+ }
+
+ /* Actually send the message out */
+ if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+ return( ret );
+ }
+ }
+
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ /* Update state and set timer */
+ if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+ else
+ {
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+ mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
+
+ return( 0 );
+}
+
+/*
+ * To be called when the last message of an incoming flight is received.
+ */
+void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
+{
+ /* We won't need to resend that one any more */
+ mbedtls_ssl_flight_free( ssl->handshake->flight );
+ ssl->handshake->flight = NULL;
+ ssl->handshake->cur_msg = NULL;
+
+ /* The next incoming flight will start with this msg_seq */
+ ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
+
+ /* We don't want to remember CCS's across flight boundaries. */
+ ssl->handshake->buffering.seen_ccs = 0;
+
+ /* Clear future message buffering structure. */
+ mbedtls_ssl_buffering_free( ssl );
+
+ /* Cancel timer */
+ mbedtls_ssl_set_timer( ssl, 0 );
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
+ {
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+ }
+ else
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
+}
+
+/*
+ * To be called when the last message of an outgoing flight is send.
+ */
+void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
+{
+ ssl_reset_retransmit_timeout( ssl );
+ mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
+ {
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+ }
+ else
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+/*
+ * Handshake layer functions
+ */
+
+/*
+ * Write (DTLS: or queue) current handshake (including CCS) message.
+ *
+ * - fill in handshake headers
+ * - update handshake checksum
+ * - DTLS: save message for resending
+ * - then pass to the record layer
+ *
+ * DTLS: except for HelloRequest, messages are only queued, and will only be
+ * actually sent when calling flight_transmit() or resend().
+ *
+ * Inputs:
+ * - ssl->out_msglen: 4 + actual handshake message len
+ * (4 is the size of handshake headers for TLS)
+ * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
+ * - ssl->out_msg + 4: the handshake message body
+ *
+ * Outputs, ie state before passing to flight_append() or write_record():
+ * - ssl->out_msglen: the length of the record contents
+ * (including handshake headers but excluding record headers)
+ * - ssl->out_msg: the record contents (handshake headers + content)
+ */
+int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const size_t hs_len = ssl->out_msglen - 4;
+ const unsigned char hs_type = ssl->out_msg[0];
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) );
+
+ /*
+ * Sanity checks
+ */
+ if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ /* In SSLv3, the client might send a NoCertificate alert. */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
+ if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
+ ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) )
+#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+
+ /* Whenever we send anything different from a
+ * HelloRequest we should be in a handshake - double check. */
+ if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
+ ssl->handshake == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->handshake != NULL &&
+ ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+#endif
+
+ /* Double-check that we did not exceed the bounds
+ * of the outgoing record buffer.
+ * This should never fail as the various message
+ * writing functions must obey the bounds of the
+ * outgoing record buffer, but better be safe.
+ *
+ * Note: We deliberately do not check for the MTU or MFL here.
+ */
+ if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
+ "size %" MBEDTLS_PRINTF_SIZET
+ ", maximum %" MBEDTLS_PRINTF_SIZET,
+ ssl->out_msglen,
+ (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /*
+ * Fill handshake headers
+ */
+ if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+ {
+ ssl->out_msg[1] = MBEDTLS_BYTE_2( hs_len );
+ ssl->out_msg[2] = MBEDTLS_BYTE_1( hs_len );
+ ssl->out_msg[3] = MBEDTLS_BYTE_0( hs_len );
+
+ /*
+ * DTLS has additional fields in the Handshake layer,
+ * between the length field and the actual payload:
+ * uint16 message_seq;
+ * uint24 fragment_offset;
+ * uint24 fragment_length;
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Make room for the additional DTLS fields */
+ if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
+ "size %" MBEDTLS_PRINTF_SIZET ", maximum %" MBEDTLS_PRINTF_SIZET,
+ hs_len,
+ (size_t) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len );
+ ssl->out_msglen += 8;
+
+ /* Write message_seq and update it, except for HelloRequest */
+ if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
+ {
+ MBEDTLS_PUT_UINT16_BE( ssl->handshake->out_msg_seq, ssl->out_msg, 4 );
+ ++( ssl->handshake->out_msg_seq );
+ }
+ else
+ {
+ ssl->out_msg[4] = 0;
+ ssl->out_msg[5] = 0;
+ }
+
+ /* Handshake hashes are computed without fragmentation,
+ * so set frag_offset = 0 and frag_len = hs_len for now */
+ memset( ssl->out_msg + 6, 0x00, 3 );
+ memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /* Update running hashes of handshake messages seen */
+ if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
+ ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
+ }
+
+ /* Either send now, or just save to be sent (and resent) later */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
+ {
+ if( ( ret = ssl_flight_append( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
+ return( ret );
+ }
+ }
+ else
+#endif
+ {
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
+ return( ret );
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
+
+ return( 0 );
+}
+
+/*
+ * Record layer functions
+ */
+
+/*
+ * Write current record.
+ *
+ * Uses:
+ * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
+ * - ssl->out_msglen: length of the record content (excl headers)
+ * - ssl->out_msg: record content
+ */
+int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
+{
+ int ret, done = 0;
+ size_t len = ssl->out_msglen;
+ uint8_t flush = force_flush;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ if( ssl->transform_out != NULL &&
+ ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+ {
+ if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
+ return( ret );
+ }
+
+ len = ssl->out_msglen;
+ }
+#endif /*MBEDTLS_ZLIB_SUPPORT */
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ if( mbedtls_ssl_hw_record_write != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
+
+ ret = mbedtls_ssl_hw_record_write( ssl );
+ if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ if( ret == 0 )
+ done = 1;
+ }
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+ if( !done )
+ {
+ unsigned i;
+ size_t protected_record_size;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+ /* Skip writing the record content type to after the encryption,
+ * as it may change when using the CID extension. */
+
+ mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+ ssl->conf->transport, ssl->out_hdr + 1 );
+
+ memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
+ MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0);
+
+ if( ssl->transform_out != NULL )
+ {
+ mbedtls_record rec;
+
+ rec.buf = ssl->out_iv;
+ rec.buf_len = out_buf_len - ( ssl->out_iv - ssl->out_buf );
+ rec.data_len = ssl->out_msglen;
+ rec.data_offset = ssl->out_msg - rec.buf;
+
+ memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
+ mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+ ssl->conf->transport, rec.ver );
+ rec.type = ssl->out_msgtype;
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* The CID is set by mbedtls_ssl_encrypt_buf(). */
+ rec.cid_len = 0;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec,
+ ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
+ return( ret );
+ }
+
+ if( rec.data_offset != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* Update the record content type and CID. */
+ ssl->out_msgtype = rec.type;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID )
+ memcpy( ssl->out_cid, rec.cid, rec.cid_len );
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->out_msglen = len = rec.data_len;
+ MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->out_len, 0 );
+ }
+
+ protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ /* In case of DTLS, double-check that we don't exceed
+ * the remaining space in the datagram. */
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ret = ssl_get_remaining_space_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+
+ if( protected_record_size > (size_t) ret )
+ {
+ /* Should never happen */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /* Now write the potentially updated record content type. */
+ ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %u, "
+ "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET,
+ ssl->out_hdr[0], ssl->out_hdr[1],
+ ssl->out_hdr[2], len ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
+ ssl->out_hdr, protected_record_size );
+
+ ssl->out_left += protected_record_size;
+ ssl->out_hdr += protected_record_size;
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
+
+ for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
+ if( ++ssl->cur_out_ctr[i - 1] != 0 )
+ break;
+
+ /* The loop goes to its end iff the counter is wrapping */
+ if( i == mbedtls_ssl_ep_len( ssl ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
+ return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+ }
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ flush == SSL_DONT_FORCE_FLUSH )
+ {
+ size_t remaining;
+ ret = ssl_get_remaining_payload_in_datagram( ssl );
+ if( ret < 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
+ ret );
+ return( ret );
+ }
+
+ remaining = (size_t) ret;
+ if( remaining == 0 )
+ {
+ flush = SSL_FORCE_FLUSH;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ if( ( flush == SSL_FORCE_FLUSH ) &&
+ ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
+ return( ret );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
+{
+ if( ssl->in_msglen < ssl->in_hslen ||
+ memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
+ memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
+ {
+ return( 1 );
+ }
+ return( 0 );
+}
+
+static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl )
+{
+ return( ( ssl->in_msg[9] << 16 ) |
+ ( ssl->in_msg[10] << 8 ) |
+ ssl->in_msg[11] );
+}
+
+static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
+{
+ return( ( ssl->in_msg[6] << 16 ) |
+ ( ssl->in_msg[7] << 8 ) |
+ ssl->in_msg[8] );
+}
+
+static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
+{
+ uint32_t msg_len, frag_off, frag_len;
+
+ msg_len = ssl_get_hs_total_len( ssl );
+ frag_off = ssl_get_hs_frag_off( ssl );
+ frag_len = ssl_get_hs_frag_len( ssl );
+
+ if( frag_off > msg_len )
+ return( -1 );
+
+ if( frag_len > msg_len - frag_off )
+ return( -1 );
+
+ if( frag_len + 12 > ssl->in_msglen )
+ return( -1 );
+
+ return( 0 );
+}
+
+/*
+ * Mark bits in bitmask (used for DTLS HS reassembly)
+ */
+static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
+{
+ unsigned int start_bits, end_bits;
+
+ start_bits = 8 - ( offset % 8 );
+ if( start_bits != 8 )
+ {
+ size_t first_byte_idx = offset / 8;
+
+ /* Special case */
+ if( len <= start_bits )
+ {
+ for( ; len != 0; len-- )
+ mask[first_byte_idx] |= 1 << ( start_bits - len );
+
+ /* Avoid potential issues with offset or len becoming invalid */
+ return;
+ }
+
+ offset += start_bits; /* Now offset % 8 == 0 */
+ len -= start_bits;
+
+ for( ; start_bits != 0; start_bits-- )
+ mask[first_byte_idx] |= 1 << ( start_bits - 1 );
+ }
+
+ end_bits = len % 8;
+ if( end_bits != 0 )
+ {
+ size_t last_byte_idx = ( offset + len ) / 8;
+
+ len -= end_bits; /* Now len % 8 == 0 */
+
+ for( ; end_bits != 0; end_bits-- )
+ mask[last_byte_idx] |= 1 << ( 8 - end_bits );
+ }
+
+ memset( mask + offset / 8, 0xFF, len / 8 );
+}
+
+/*
+ * Check that bitmask is full
+ */
+static int ssl_bitmask_check( unsigned char *mask, size_t len )
+{
+ size_t i;
+
+ for( i = 0; i < len / 8; i++ )
+ if( mask[i] != 0xFF )
+ return( -1 );
+
+ for( i = 0; i < len % 8; i++ )
+ if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
+ return( -1 );
+
+ return( 0 );
+}
+
+/* msg_len does not include the handshake header */
+static size_t ssl_get_reassembly_buffer_size( size_t msg_len,
+ unsigned add_bitmap )
+{
+ size_t alloc_len;
+
+ alloc_len = 12; /* Handshake header */
+ alloc_len += msg_len; /* Content buffer */
+
+ if( add_bitmap )
+ alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */
+
+ return( alloc_len );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl )
+{
+ return( ( ssl->in_msg[1] << 16 ) |
+ ( ssl->in_msg[2] << 8 ) |
+ ssl->in_msg[3] );
+}
+
+int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
+{
+ if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
+ " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
+
+ if( ssl_check_hs_header( ssl ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ if( ssl->handshake != NULL &&
+ ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
+ recv_msg_seq != ssl->handshake->in_msg_seq ) ||
+ ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
+ ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) )
+ {
+ if( recv_msg_seq > ssl->handshake->in_msg_seq )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)",
+ recv_msg_seq,
+ ssl->handshake->in_msg_seq ) );
+ return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+ }
+
+ /* Retransmit only on last message from previous flight, to avoid
+ * too many retransmissions.
+ * Besides, No sane server ever retransmits HelloVerifyRequest */
+ if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
+ ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
+ "message_seq = %u, start_of_flight = %u",
+ recv_msg_seq,
+ ssl->handshake->in_flight_start_seq ) );
+
+ if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
+ return( ret );
+ }
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
+ "message_seq = %u, expected = %u",
+ recv_msg_seq,
+ ssl->handshake->in_msg_seq ) );
+ }
+
+ return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+ }
+ /* Wait until message completion to increment in_msg_seq */
+
+ /* Message reassembly is handled alongside buffering of future
+ * messages; the commonality is that both handshake fragments and
+ * future messages cannot be forwarded immediately to the
+ * handshake logic layer. */
+ if( ssl_hs_is_proper_fragment( ssl ) == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
+ return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ /* With TLS we don't handle fragmentation (for now) */
+ if( ssl->in_msglen < ssl->in_hslen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
+
+ return( 0 );
+}
+
+void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
+ {
+ ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
+ }
+
+ /* Handshake message is complete, increment counter */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->handshake != NULL )
+ {
+ unsigned offset;
+ mbedtls_ssl_hs_buffer *hs_buf;
+
+ /* Increment handshake sequence number */
+ hs->in_msg_seq++;
+
+ /*
+ * Clear up handshake buffering and reassembly structure.
+ */
+
+ /* Free first entry */
+ ssl_buffering_free_slot( ssl, 0 );
+
+ /* Shift all other entries */
+ for( offset = 0, hs_buf = &hs->buffering.hs[0];
+ offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
+ offset++, hs_buf++ )
+ {
+ *hs_buf = *(hs_buf + 1);
+ }
+
+ /* Create a fresh last entry */
+ memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
+ }
+#endif
+}
+
+/*
+ * DTLS anti-replay: RFC 6347 4.1.2.6
+ *
+ * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
+ * Bit n is set iff record number in_window_top - n has been seen.
+ *
+ * Usually, in_window_top is the last record number seen and the lsb of
+ * in_window is set. The only exception is the initial state (record number 0
+ * not seen yet).
+ */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
+{
+ ssl->in_window_top = 0;
+ ssl->in_window = 0;
+}
+
+static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
+{
+ return( ( (uint64_t) buf[0] << 40 ) |
+ ( (uint64_t) buf[1] << 32 ) |
+ ( (uint64_t) buf[2] << 24 ) |
+ ( (uint64_t) buf[3] << 16 ) |
+ ( (uint64_t) buf[4] << 8 ) |
+ ( (uint64_t) buf[5] ) );
+}
+
+static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *original_in_ctr;
+
+ // save original in_ctr
+ original_in_ctr = ssl->in_ctr;
+
+ // use counter from record
+ ssl->in_ctr = record_in_ctr;
+
+ ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl );
+
+ // restore the counter
+ ssl->in_ctr = original_in_ctr;
+
+ return ret;
+}
+
+/*
+ * Return 0 if sequence number is acceptable, -1 otherwise
+ */
+int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl )
+{
+ uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
+ uint64_t bit;
+
+ if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
+ return( 0 );
+
+ if( rec_seqnum > ssl->in_window_top )
+ return( 0 );
+
+ bit = ssl->in_window_top - rec_seqnum;
+
+ if( bit >= 64 )
+ return( -1 );
+
+ if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
+ return( -1 );
+
+ return( 0 );
+}
+
+/*
+ * Update replay window on new validated record
+ */
+void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
+{
+ uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
+
+ if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
+ return;
+
+ if( rec_seqnum > ssl->in_window_top )
+ {
+ /* Update window_top and the contents of the window */
+ uint64_t shift = rec_seqnum - ssl->in_window_top;
+
+ if( shift >= 64 )
+ ssl->in_window = 1;
+ else
+ {
+ ssl->in_window <<= shift;
+ ssl->in_window |= 1;
+ }
+
+ ssl->in_window_top = rec_seqnum;
+ }
+ else
+ {
+ /* Mark that number as seen in the current window */
+ uint64_t bit = ssl->in_window_top - rec_seqnum;
+
+ if( bit < 64 ) /* Always true, but be extra sure */
+ ssl->in_window |= (uint64_t) 1 << bit;
+ }
+}
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+/*
+ * Without any SSL context, check if a datagram looks like a ClientHello with
+ * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
+ * Both input and output include full DTLS headers.
+ *
+ * - if cookie is valid, return 0
+ * - if ClientHello looks superficially valid but cookie is not,
+ * fill obuf and set olen, then
+ * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
+ * - otherwise return a specific error code
+ */
+static int ssl_check_dtls_clihlo_cookie(
+ mbedtls_ssl_cookie_write_t *f_cookie_write,
+ mbedtls_ssl_cookie_check_t *f_cookie_check,
+ void *p_cookie,
+ const unsigned char *cli_id, size_t cli_id_len,
+ const unsigned char *in, size_t in_len,
+ unsigned char *obuf, size_t buf_len, size_t *olen )
+{
+ size_t sid_len, cookie_len;
+ unsigned char *p;
+
+ /*
+ * Structure of ClientHello with record and handshake headers,
+ * and expected values. We don't need to check a lot, more checks will be
+ * done when actually parsing the ClientHello - skipping those checks
+ * avoids code duplication and does not make cookie forging any easier.
+ *
+ * 0-0 ContentType type; copied, must be handshake
+ * 1-2 ProtocolVersion version; copied
+ * 3-4 uint16 epoch; copied, must be 0
+ * 5-10 uint48 sequence_number; copied
+ * 11-12 uint16 length; (ignored)
+ *
+ * 13-13 HandshakeType msg_type; (ignored)
+ * 14-16 uint24 length; (ignored)
+ * 17-18 uint16 message_seq; copied
+ * 19-21 uint24 fragment_offset; copied, must be 0
+ * 22-24 uint24 fragment_length; (ignored)
+ *
+ * 25-26 ProtocolVersion client_version; (ignored)
+ * 27-58 Random random; (ignored)
+ * 59-xx SessionID session_id; 1 byte len + sid_len content
+ * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
+ * ...
+ *
+ * Minimum length is 61 bytes.
+ */
+ if( in_len < 61 ||
+ in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
+ in[3] != 0 || in[4] != 0 ||
+ in[19] != 0 || in[20] != 0 || in[21] != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ sid_len = in[59];
+ if( sid_len > in_len - 61 )
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+
+ cookie_len = in[60 + sid_len];
+ if( cookie_len > in_len - 60 )
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+
+ if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
+ cli_id, cli_id_len ) == 0 )
+ {
+ /* Valid cookie */
+ return( 0 );
+ }
+
+ /*
+ * If we get here, we've got an invalid cookie, let's prepare HVR.
+ *
+ * 0-0 ContentType type; copied
+ * 1-2 ProtocolVersion version; copied
+ * 3-4 uint16 epoch; copied
+ * 5-10 uint48 sequence_number; copied
+ * 11-12 uint16 length; olen - 13
+ *
+ * 13-13 HandshakeType msg_type; hello_verify_request
+ * 14-16 uint24 length; olen - 25
+ * 17-18 uint16 message_seq; copied
+ * 19-21 uint24 fragment_offset; copied
+ * 22-24 uint24 fragment_length; olen - 25
+ *
+ * 25-26 ProtocolVersion server_version; 0xfe 0xff
+ * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
+ *
+ * Minimum length is 28.
+ */
+ if( buf_len < 28 )
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+ /* Copy most fields and adapt others */
+ memcpy( obuf, in, 25 );
+ obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
+ obuf[25] = 0xfe;
+ obuf[26] = 0xff;
+
+ /* Generate and write actual cookie */
+ p = obuf + 28;
+ if( f_cookie_write( p_cookie,
+ &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ *olen = p - obuf;
+
+ /* Go back and fill length fields */
+ obuf[27] = (unsigned char)( *olen - 28 );
+
+ obuf[14] = obuf[22] = MBEDTLS_BYTE_2( *olen - 25 );
+ obuf[15] = obuf[23] = MBEDTLS_BYTE_1( *olen - 25 );
+ obuf[16] = obuf[24] = MBEDTLS_BYTE_0( *olen - 25 );
+
+ MBEDTLS_PUT_UINT16_BE( *olen - 13, obuf, 11 );
+
+ return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
+}
+
+/*
+ * Handle possible client reconnect with the same UDP quadruplet
+ * (RFC 6347 Section 4.2.8).
+ *
+ * Called by ssl_parse_record_header() in case we receive an epoch 0 record
+ * that looks like a ClientHello.
+ *
+ * - if the input looks like a ClientHello without cookies,
+ * send back HelloVerifyRequest, then return 0
+ * - if the input looks like a ClientHello with a valid cookie,
+ * reset the session of the current context, and
+ * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
+ * - if anything goes wrong, return a specific error code
+ *
+ * This function is called (through ssl_check_client_reconnect()) when an
+ * unexpected record is found in ssl_get_next_record(), which will discard the
+ * record if we return 0, and bubble up the return value otherwise (this
+ * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
+ * errors, and is the right thing to do in both cases).
+ */
+static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len;
+
+ if( ssl->conf->f_cookie_write == NULL ||
+ ssl->conf->f_cookie_check == NULL )
+ {
+ /* If we can't use cookies to verify reachability of the peer,
+ * drop the record. */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "no cookie callbacks, "
+ "can't check reconnect validity" ) );
+ return( 0 );
+ }
+
+ ret = ssl_check_dtls_clihlo_cookie(
+ ssl->conf->f_cookie_write,
+ ssl->conf->f_cookie_check,
+ ssl->conf->p_cookie,
+ ssl->cli_id, ssl->cli_id_len,
+ ssl->in_buf, ssl->in_left,
+ ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
+
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
+
+ if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
+ {
+ int send_ret;
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
+ ssl->out_buf, len );
+ /* Don't check write errors as we can't do anything here.
+ * If the error is permanent we'll catch it later,
+ * if it's not, then hopefully it'll work next time. */
+ send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
+ (void) send_ret;
+
+ return( 0 );
+ }
+
+ if( ret == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
+ if( ( ret = mbedtls_ssl_session_reset_int( ssl, 1 ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
+ return( ret );
+ }
+
+ return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
+ }
+
+ return( ret );
+}
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+
+static int ssl_check_record_type( uint8_t record_type )
+{
+ if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
+ record_type != MBEDTLS_SSL_MSG_ALERT &&
+ record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
+ record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+ {
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ return( 0 );
+}
+
+/*
+ * ContentType type;
+ * ProtocolVersion version;
+ * uint16 epoch; // DTLS only
+ * uint48 sequence_number; // DTLS only
+ * uint16 length;
+ *
+ * Return 0 if header looks sane (and, for DTLS, the record is expected)
+ * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
+ * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
+ *
+ * With DTLS, mbedtls_ssl_read_record() will:
+ * 1. proceed with the record if this function returns 0
+ * 2. drop only the current record if this function returns UNEXPECTED_RECORD
+ * 3. return CLIENT_RECONNECT if this function return that value
+ * 4. drop the whole datagram if this function returns anything else.
+ * Point 2 is needed when the peer is resending, and we have already received
+ * the first record from a datagram but are still waiting for the others.
+ */
+static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
+ unsigned char *buf,
+ size_t len,
+ mbedtls_record *rec )
+{
+ int major_ver, minor_ver;
+
+ size_t const rec_hdr_type_offset = 0;
+ size_t const rec_hdr_type_len = 1;
+
+ size_t const rec_hdr_version_offset = rec_hdr_type_offset +
+ rec_hdr_type_len;
+ size_t const rec_hdr_version_len = 2;
+
+ size_t const rec_hdr_ctr_len = 8;
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint32_t rec_epoch;
+ size_t const rec_hdr_ctr_offset = rec_hdr_version_offset +
+ rec_hdr_version_len;
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset +
+ rec_hdr_ctr_len;
+ size_t rec_hdr_cid_len = 0;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ size_t rec_hdr_len_offset; /* To be determined */
+ size_t const rec_hdr_len_len = 2;
+
+ /*
+ * Check minimum lengths for record header.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len;
+ }
+
+ if( len < rec_hdr_len_offset + rec_hdr_len_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header of length %u",
+ (unsigned) len,
+ (unsigned)( rec_hdr_len_len + rec_hdr_len_len ) ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ /*
+ * Parse and validate record content type
+ */
+
+ rec->type = buf[ rec_hdr_type_offset ];
+
+ /* Check record content type */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ rec->cid_len = 0;
+
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->conf->cid_len != 0 &&
+ rec->type == MBEDTLS_SSL_MSG_CID )
+ {
+ /* Shift pointers to account for record header including CID
+ * struct {
+ * ContentType special_type = tls12_cid;
+ * ProtocolVersion version;
+ * uint16 epoch;
+ * uint48 sequence_number;
+ * opaque cid[cid_length]; // Additional field compared to
+ * // default DTLS record format
+ * uint16 length;
+ * opaque enc_content[DTLSCiphertext.length];
+ * } DTLSCiphertext;
+ */
+
+ /* So far, we only support static CID lengths
+ * fixed in the configuration. */
+ rec_hdr_cid_len = ssl->conf->cid_len;
+ rec_hdr_len_offset += rec_hdr_cid_len;
+
+ if( len < rec_hdr_len_offset + rec_hdr_len_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header including CID, length %u",
+ (unsigned) len,
+ (unsigned)( rec_hdr_len_offset + rec_hdr_len_len ) ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ /* configured CID len is guaranteed at most 255, see
+ * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */
+ rec->cid_len = (uint8_t) rec_hdr_cid_len;
+ memcpy( rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len );
+ }
+ else
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ {
+ if( ssl_check_record_type( rec->type ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type %u",
+ (unsigned) rec->type ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+ }
+
+ /*
+ * Parse and validate record version
+ */
+
+ rec->ver[0] = buf[ rec_hdr_version_offset + 0 ];
+ rec->ver[1] = buf[ rec_hdr_version_offset + 1 ];
+ mbedtls_ssl_read_version( &major_ver, &minor_ver,
+ ssl->conf->transport,
+ &rec->ver[0] );
+
+ if( major_ver != ssl->major_ver )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ if( minor_ver > ssl->conf->max_minor_ver )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ /*
+ * Parse/Copy record sequence number.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Copy explicit record sequence number from input buffer. */
+ memcpy( &rec->ctr[0], buf + rec_hdr_ctr_offset,
+ rec_hdr_ctr_len );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ /* Copy implicit record sequence number from SSL context structure. */
+ memcpy( &rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len );
+ }
+
+ /*
+ * Parse record length.
+ */
+
+ rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
+ rec->data_len = ( (size_t) buf[ rec_hdr_len_offset + 0 ] << 8 ) |
+ ( (size_t) buf[ rec_hdr_len_offset + 1 ] << 0 );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", buf, rec->data_offset );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %u, "
+ "version = [%d:%d], msglen = %" MBEDTLS_PRINTF_SIZET,
+ rec->type,
+ major_ver, minor_ver, rec->data_len ) );
+
+ rec->buf = buf;
+ rec->buf_len = rec->data_offset + rec->data_len;
+
+ if( rec->data_len == 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+
+ /*
+ * DTLS-related tests.
+ * Check epoch before checking length constraint because
+ * the latter varies with the epoch. E.g., if a ChangeCipherSpec
+ * message gets duplicated before the corresponding Finished message,
+ * the second ChangeCipherSpec should be discarded because it belongs
+ * to an old epoch, but not because its length is shorter than
+ * the minimum record length for packets using the new record transform.
+ * Note that these two kinds of failures are handled differently,
+ * as an unexpected record is silently skipped but an invalid
+ * record leads to the entire datagram being dropped.
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ rec_epoch = ( rec->ctr[0] << 8 ) | rec->ctr[1];
+
+ /* Check that the datagram is large enough to contain a record
+ * of the advertised length. */
+ if( len < rec->data_offset + rec->data_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Datagram of length %u too small to contain record of advertised length %u.",
+ (unsigned) len,
+ (unsigned)( rec->data_offset + rec->data_len ) ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ /* Records from other, non-matching epochs are silently discarded.
+ * (The case of same-port Client reconnects must be considered in
+ * the caller). */
+ if( rec_epoch != ssl->in_epoch )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
+ "expected %u, received %lu",
+ ssl->in_epoch, (unsigned long) rec_epoch ) );
+
+ /* Records from the next epoch are considered for buffering
+ * (concretely: early Finished messages). */
+ if( rec_epoch == (unsigned) ssl->in_epoch + 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) );
+ return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+ }
+
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+ }
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ /* For records from the correct epoch, check whether their
+ * sequence number has been seen before. */
+ else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl,
+ &rec->ctr[0] ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+ }
+#endif
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ return( 0 );
+}
+
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl )
+{
+ unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
+
+ /*
+ * Check for an epoch 0 ClientHello. We can't use in_msg here to
+ * access the first byte of record content (handshake type), as we
+ * have an active transform (possibly iv_len != 0), so use the
+ * fact that the record header len is 13 instead.
+ */
+ if( rec_epoch == 0 &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
+ ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->in_left > 13 &&
+ ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
+ "from the same port" ) );
+ return( ssl_handle_possible_reconnect( ssl ) );
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+
+/*
+ * If applicable, decrypt record content
+ */
+static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
+ mbedtls_record *rec )
+{
+ int ret, done = 0;
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
+ rec->buf, rec->buf_len );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ if( mbedtls_ssl_hw_record_read != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
+
+ ret = mbedtls_ssl_hw_record_read( ssl );
+ if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ if( ret == 0 )
+ done = 1;
+ }
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+ if( !done && ssl->transform_in != NULL )
+ {
+ unsigned char const old_msg_type = rec->type;
+
+ if( ( ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in,
+ rec ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
+ ssl->conf->ignore_unexpected_cid
+ == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) );
+ ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ return( ret );
+ }
+
+ if( old_msg_type != rec->type )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d",
+ old_msg_type, rec->type ) );
+ }
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
+ rec->buf + rec->data_offset, rec->data_len );
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* We have already checked the record content type
+ * in ssl_parse_record_header(), failing or silently
+ * dropping the record in the case of an unknown type.
+ *
+ * Since with the use of CIDs, the record content type
+ * might change during decryption, re-check the record
+ * content type, but treat a failure as fatal this time. */
+ if( ssl_check_record_type( rec->type ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ if( rec->data_len == 0 )
+ {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
+ && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+ {
+ /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ ssl->nb_zero++;
+
+ /*
+ * Three or more empty messages may be a DoS attack
+ * (excessive CPU consumption).
+ */
+ if( ssl->nb_zero > 3 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
+ "messages, possible DoS attack" ) );
+ /* Treat the records as if they were not properly authenticated,
+ * thereby failing the connection if we see more than allowed
+ * by the configured bad MAC threshold. */
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+ }
+ else
+ ssl->nb_zero = 0;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ; /* in_ctr read from peer, not maintained internally */
+ }
+ else
+#endif
+ {
+ unsigned i;
+ for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
+ if( ++ssl->in_ctr[i - 1] != 0 )
+ break;
+
+ /* The loop goes to its end iff the counter is wrapping */
+ if( i == mbedtls_ssl_ep_len( ssl ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
+ return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+ }
+ }
+
+ }
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ mbedtls_ssl_dtls_replay_update( ssl );
+ }
+#endif
+
+ /* Check actual (decrypted) record content length against
+ * configured maximum. */
+ if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Read a record.
+ *
+ * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
+ * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
+ *
+ */
+
+/* Helper functions for mbedtls_ssl_read_record(). */
+static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
+static int ssl_get_next_record( mbedtls_ssl_context *ssl );
+static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
+ unsigned update_hs_digest )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
+
+ if( ssl->keep_current_message == 0 )
+ {
+ do {
+
+ ret = ssl_consume_current_message( ssl );
+ if( ret != 0 )
+ return( ret );
+
+ if( ssl_record_is_in_progress( ssl ) == 0 )
+ {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ int have_buffered = 0;
+
+ /* We only check for buffered messages if the
+ * current datagram is fully consumed. */
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl_next_record_is_in_datagram( ssl ) == 0 )
+ {
+ if( ssl_load_buffered_message( ssl ) == 0 )
+ have_buffered = 1;
+ }
+
+ if( have_buffered == 0 )
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ ret = ssl_get_next_record( ssl );
+ if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
+ continue;
+
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
+ return( ret );
+ }
+ }
+ }
+
+ ret = mbedtls_ssl_handle_message_type( ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
+ {
+ /* Buffer future message */
+ ret = ssl_buffer_message( ssl );
+ if( ret != 0 )
+ return( ret );
+
+ ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ||
+ MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret );
+
+ if( 0 != ret )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
+ return( ret );
+ }
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ update_hs_digest == 1 )
+ {
+ mbedtls_ssl_update_handshake_status( ssl );
+ }
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
+ ssl->keep_current_message = 0;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
+{
+ if( ssl->in_left > ssl->next_record_offset )
+ return( 1 );
+
+ return( 0 );
+}
+
+static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ mbedtls_ssl_hs_buffer * hs_buf;
+ int ret = 0;
+
+ if( hs == NULL )
+ return( -1 );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) );
+
+ if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
+ ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
+ {
+ /* Check if we have seen a ChangeCipherSpec before.
+ * If yes, synthesize a CCS record. */
+ if( !hs->buffering.seen_ccs )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) );
+ ret = -1;
+ goto exit;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) );
+ ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
+ ssl->in_msglen = 1;
+ ssl->in_msg[0] = 1;
+
+ /* As long as they are equal, the exact value doesn't matter. */
+ ssl->in_left = 0;
+ ssl->next_record_offset = 0;
+
+ hs->buffering.seen_ccs = 0;
+ goto exit;
+ }
+
+#if defined(MBEDTLS_DEBUG_C)
+ /* Debug only */
+ {
+ unsigned offset;
+ for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
+ {
+ hs_buf = &hs->buffering.hs[offset];
+ if( hs_buf->is_valid == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.",
+ hs->in_msg_seq + offset,
+ hs_buf->is_complete ? "fully" : "partially" ) );
+ }
+ }
+ }
+#endif /* MBEDTLS_DEBUG_C */
+
+ /* Check if we have buffered and/or fully reassembled the
+ * next handshake message. */
+ hs_buf = &hs->buffering.hs[0];
+ if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) )
+ {
+ /* Synthesize a record containing the buffered HS message. */
+ size_t msg_len = ( hs_buf->data[1] << 16 ) |
+ ( hs_buf->data[2] << 8 ) |
+ hs_buf->data[3];
+
+ /* Double-check that we haven't accidentally buffered
+ * a message that doesn't fit into the input buffer. */
+ if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)",
+ hs_buf->data, msg_len + 12 );
+
+ ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+ ssl->in_hslen = msg_len + 12;
+ ssl->in_msglen = msg_len + 12;
+ memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen );
+
+ ret = 0;
+ goto exit;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered",
+ hs->in_msg_seq ) );
+ }
+
+ ret = -1;
+
+exit:
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) );
+ return( ret );
+}
+
+static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
+ size_t desired )
+{
+ int offset;
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available",
+ (unsigned) desired ) );
+
+ /* Get rid of future records epoch first, if such exist. */
+ ssl_free_buffered_record( ssl );
+
+ /* Check if we have enough space available now. */
+ if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+ hs->buffering.total_bytes_buffered ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) );
+ return( 0 );
+ }
+
+ /* We don't have enough space to buffer the next expected handshake
+ * message. Remove buffers used for future messages to gain space,
+ * starting with the most distant one. */
+ for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
+ offset >= 0; offset-- )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message",
+ offset ) );
+
+ ssl_buffering_free_slot( ssl, (uint8_t) offset );
+
+ /* Check if we have enough space available now. */
+ if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+ hs->buffering.total_bytes_buffered ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) );
+ return( 0 );
+ }
+ }
+
+ return( -1 );
+}
+
+static int ssl_buffer_message( mbedtls_ssl_context *ssl )
+{
+ int ret = 0;
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+ if( hs == NULL )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) );
+
+ switch( ssl->in_msgtype )
+ {
+ case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) );
+
+ hs->buffering.seen_ccs = 1;
+ break;
+
+ case MBEDTLS_SSL_MSG_HANDSHAKE:
+ {
+ unsigned recv_msg_seq_offset;
+ unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
+ mbedtls_ssl_hs_buffer *hs_buf;
+ size_t msg_len = ssl->in_hslen - 12;
+
+ /* We should never receive an old handshake
+ * message - double-check nonetheless. */
+ if( recv_msg_seq < ssl->handshake->in_msg_seq )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
+ if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS )
+ {
+ /* Silently ignore -- message too far in the future */
+ MBEDTLS_SSL_DEBUG_MSG( 2,
+ ( "Ignore future HS message with sequence number %u, "
+ "buffering window %u - %u",
+ recv_msg_seq, ssl->handshake->in_msg_seq,
+ ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) );
+
+ goto exit;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ",
+ recv_msg_seq, recv_msg_seq_offset ) );
+
+ hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ];
+
+ /* Check if the buffering for this seq nr has already commenced. */
+ if( !hs_buf->is_valid )
+ {
+ size_t reassembly_buf_sz;
+
+ hs_buf->is_fragmented =
+ ( ssl_hs_is_proper_fragment( ssl ) == 1 );
+
+ /* We copy the message back into the input buffer
+ * after reassembly, so check that it's not too large.
+ * This is an implementation-specific limitation
+ * and not one from the standard, hence it is not
+ * checked in ssl_check_hs_header(). */
+ if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
+ {
+ /* Ignore message */
+ goto exit;
+ }
+
+ /* Check if we have enough space to buffer the message. */
+ if( hs->buffering.total_bytes_buffered >
+ MBEDTLS_SSL_DTLS_MAX_BUFFERING )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
+ hs_buf->is_fragmented );
+
+ if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+ hs->buffering.total_bytes_buffered ) )
+ {
+ if( recv_msg_seq_offset > 0 )
+ {
+ /* If we can't buffer a future message because
+ * of space limitations -- ignore. */
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET
+ " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
+ " (already %" MBEDTLS_PRINTF_SIZET
+ " bytes buffered) -- ignore\n",
+ msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+ hs->buffering.total_bytes_buffered ) );
+ goto exit;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET
+ " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
+ " (already %" MBEDTLS_PRINTF_SIZET
+ " bytes buffered) -- attempt to make space by freeing buffered future messages\n",
+ msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+ hs->buffering.total_bytes_buffered ) );
+ }
+
+ if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %" MBEDTLS_PRINTF_SIZET
+ " (%" MBEDTLS_PRINTF_SIZET " with bitmap) would exceed"
+ " the compile-time limit %" MBEDTLS_PRINTF_SIZET
+ " (already %" MBEDTLS_PRINTF_SIZET
+ " bytes buffered) -- fail\n",
+ msg_len,
+ reassembly_buf_sz,
+ (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+ hs->buffering.total_bytes_buffered ) );
+ ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
+ goto exit;
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %" MBEDTLS_PRINTF_SIZET,
+ msg_len ) );
+
+ hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
+ if( hs_buf->data == NULL )
+ {
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ goto exit;
+ }
+ hs_buf->data_len = reassembly_buf_sz;
+
+ /* Prepare final header: copy msg_type, length and message_seq,
+ * then add standardised fragment_offset and fragment_length */
+ memcpy( hs_buf->data, ssl->in_msg, 6 );
+ memset( hs_buf->data + 6, 0, 3 );
+ memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
+
+ hs_buf->is_valid = 1;
+
+ hs->buffering.total_bytes_buffered += reassembly_buf_sz;
+ }
+ else
+ {
+ /* Make sure msg_type and length are consistent */
+ if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) );
+ /* Ignore */
+ goto exit;
+ }
+ }
+
+ if( !hs_buf->is_complete )
+ {
+ size_t frag_len, frag_off;
+ unsigned char * const msg = hs_buf->data + 12;
+
+ /*
+ * Check and copy current fragment
+ */
+
+ /* Validation of header fields already done in
+ * mbedtls_ssl_prepare_handshake_record(). */
+ frag_off = ssl_get_hs_frag_off( ssl );
+ frag_len = ssl_get_hs_frag_len( ssl );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %" MBEDTLS_PRINTF_SIZET
+ ", length = %" MBEDTLS_PRINTF_SIZET,
+ frag_off, frag_len ) );
+ memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
+
+ if( hs_buf->is_fragmented )
+ {
+ unsigned char * const bitmask = msg + msg_len;
+ ssl_bitmask_set( bitmask, frag_off, frag_len );
+ hs_buf->is_complete = ( ssl_bitmask_check( bitmask,
+ msg_len ) == 0 );
+ }
+ else
+ {
+ hs_buf->is_complete = 1;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete",
+ hs_buf->is_complete ? "" : "not yet " ) );
+ }
+
+ break;
+ }
+
+ default:
+ /* We don't buffer other types of messages. */
+ break;
+ }
+
+exit:
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) );
+ return( ret );
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
+{
+ /*
+ * Consume last content-layer message and potentially
+ * update in_msglen which keeps track of the contents'
+ * consumption state.
+ *
+ * (1) Handshake messages:
+ * Remove last handshake message, move content
+ * and adapt in_msglen.
+ *
+ * (2) Alert messages:
+ * Consume whole record content, in_msglen = 0.
+ *
+ * (3) Change cipher spec:
+ * Consume whole record content, in_msglen = 0.
+ *
+ * (4) Application data:
+ * Don't do anything - the record layer provides
+ * the application data as a stream transport
+ * and consumes through mbedtls_ssl_read only.
+ *
+ */
+
+ /* Case (1): Handshake messages */
+ if( ssl->in_hslen != 0 )
+ {
+ /* Hard assertion to be sure that no application data
+ * is in flight, as corrupting ssl->in_msglen during
+ * ssl->in_offt != NULL is fatal. */
+ if( ssl->in_offt != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /*
+ * Get next Handshake message in the current record
+ */
+
+ /* Notes:
+ * (1) in_hslen is not necessarily the size of the
+ * current handshake content: If DTLS handshake
+ * fragmentation is used, that's the fragment
+ * size instead. Using the total handshake message
+ * size here is faulty and should be changed at
+ * some point.
+ * (2) While it doesn't seem to cause problems, one
+ * has to be very careful not to assume that in_hslen
+ * is always <= in_msglen in a sensible communication.
+ * Again, it's wrong for DTLS handshake fragmentation.
+ * The following check is therefore mandatory, and
+ * should not be treated as a silently corrected assertion.
+ * Additionally, ssl->in_hslen might be arbitrarily out of
+ * bounds after handling a DTLS message with an unexpected
+ * sequence number, see mbedtls_ssl_prepare_handshake_record.
+ */
+ if( ssl->in_hslen < ssl->in_msglen )
+ {
+ ssl->in_msglen -= ssl->in_hslen;
+ memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
+ ssl->in_msglen );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
+ ssl->in_msg, ssl->in_msglen );
+ }
+ else
+ {
+ ssl->in_msglen = 0;
+ }
+
+ ssl->in_hslen = 0;
+ }
+ /* Case (4): Application data */
+ else if( ssl->in_offt != NULL )
+ {
+ return( 0 );
+ }
+ /* Everything else (CCS & Alerts) */
+ else
+ {
+ ssl->in_msglen = 0;
+ }
+
+ return( 0 );
+}
+
+static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
+{
+ if( ssl->in_msglen > 0 )
+ return( 1 );
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ if( hs == NULL )
+ return;
+
+ if( hs->buffering.future_record.data != NULL )
+ {
+ hs->buffering.total_bytes_buffered -=
+ hs->buffering.future_record.len;
+
+ mbedtls_free( hs->buffering.future_record.data );
+ hs->buffering.future_record.data = NULL;
+ }
+}
+
+static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ unsigned char * rec;
+ size_t rec_len;
+ unsigned rec_epoch;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ return( 0 );
+
+ if( hs == NULL )
+ return( 0 );
+
+ rec = hs->buffering.future_record.data;
+ rec_len = hs->buffering.future_record.len;
+ rec_epoch = hs->buffering.future_record.epoch;
+
+ if( rec == NULL )
+ return( 0 );
+
+ /* Only consider loading future records if the
+ * input buffer is empty. */
+ if( ssl_next_record_is_in_datagram( ssl ) == 1 )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) );
+
+ if( rec_epoch != ssl->in_epoch )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) );
+ goto exit;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
+
+ /* Double-check that the record is not too large */
+ if( rec_len > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ memcpy( ssl->in_hdr, rec, rec_len );
+ ssl->in_left = rec_len;
+ ssl->next_record_offset = 0;
+
+ ssl_free_buffered_record( ssl );
+
+exit:
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) );
+ return( 0 );
+}
+
+static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
+ mbedtls_record const *rec )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+ /* Don't buffer future records outside handshakes. */
+ if( hs == NULL )
+ return( 0 );
+
+ /* Only buffer handshake records (we are only interested
+ * in Finished messages). */
+ if( rec->type != MBEDTLS_SSL_MSG_HANDSHAKE )
+ return( 0 );
+
+ /* Don't buffer more than one future epoch record. */
+ if( hs->buffering.future_record.data != NULL )
+ return( 0 );
+
+ /* Don't buffer record if there's not enough buffering space remaining. */
+ if( rec->buf_len > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+ hs->buffering.total_bytes_buffered ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET
+ " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
+ " (already %" MBEDTLS_PRINTF_SIZET
+ " bytes buffered) -- ignore\n",
+ rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+ hs->buffering.total_bytes_buffered ) );
+ return( 0 );
+ }
+
+ /* Buffer record */
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u",
+ ssl->in_epoch + 1U ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", rec->buf, rec->buf_len );
+
+ /* ssl_parse_record_header() only considers records
+ * of the next epoch as candidates for buffering. */
+ hs->buffering.future_record.epoch = ssl->in_epoch + 1;
+ hs->buffering.future_record.len = rec->buf_len;
+
+ hs->buffering.future_record.data =
+ mbedtls_calloc( 1, hs->buffering.future_record.len );
+ if( hs->buffering.future_record.data == NULL )
+ {
+ /* If we run out of RAM trying to buffer a
+ * record from the next epoch, just ignore. */
+ return( 0 );
+ }
+
+ memcpy( hs->buffering.future_record.data, rec->buf, rec->buf_len );
+
+ hs->buffering.total_bytes_buffered += rec->buf_len;
+ return( 0 );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static int ssl_get_next_record( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_record rec;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ /* We might have buffered a future record; if so,
+ * and if the epoch matches now, load it.
+ * On success, this call will set ssl->in_left to
+ * the length of the buffered record, so that
+ * the calls to ssl_fetch_input() below will
+ * essentially be no-ops. */
+ ret = ssl_load_buffered_record( ssl );
+ if( ret != 0 )
+ return( ret );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /* Ensure that we have enough space available for the default form
+ * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
+ * with no space for CIDs counted in). */
+ ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+ return( ret );
+ }
+
+ ret = ssl_parse_record_header( ssl, ssl->in_hdr, ssl->in_left, &rec );
+ if( ret != 0 )
+ {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
+ {
+ ret = ssl_buffer_future_record( ssl, &rec );
+ if( ret != 0 )
+ return( ret );
+
+ /* Fall through to handling of unexpected records */
+ ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
+ }
+
+ if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
+ {
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+ /* Reset in pointers to default state for TLS/DTLS records,
+ * assuming no CID and no offset between record content and
+ * record plaintext. */
+ mbedtls_ssl_update_in_pointers( ssl );
+
+ /* Setup internal message pointers from record structure. */
+ ssl->in_msgtype = rec.type;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->in_len = ssl->in_cid + rec.cid_len;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->in_iv = ssl->in_msg = ssl->in_len + 2;
+ ssl->in_msglen = rec.data_len;
+
+ ret = ssl_check_client_reconnect( ssl );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_client_reconnect", ret );
+ if( ret != 0 )
+ return( ret );
+#endif
+
+ /* Skip unexpected record (but not whole datagram) */
+ ssl->next_record_offset = rec.buf_len;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
+ "(header)" ) );
+ }
+ else
+ {
+ /* Skip invalid record and the rest of the datagram */
+ ssl->next_record_offset = 0;
+ ssl->in_left = 0;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
+ "(header)" ) );
+ }
+
+ /* Get next record */
+ return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+ }
+ else
+#endif
+ {
+ return( ret );
+ }
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Remember offset of next record within datagram. */
+ ssl->next_record_offset = rec.buf_len;
+ if( ssl->next_record_offset < ssl->in_left )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
+ }
+ }
+ else
+#endif
+ {
+ /*
+ * Fetch record contents from underlying transport.
+ */
+ ret = mbedtls_ssl_fetch_input( ssl, rec.buf_len );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+ return( ret );
+ }
+
+ ssl->in_left = 0;
+ }
+
+ /*
+ * Decrypt record contents.
+ */
+
+ if( ( ret = ssl_prepare_record_content( ssl, &rec ) ) != 0 )
+ {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Silently discard invalid records */
+ if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+ {
+ /* Except when waiting for Finished as a bad mac here
+ * probably means something went wrong in the handshake
+ * (eg wrong psk used, mitm downgrade attempt, etc.) */
+ if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
+ ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
+ {
+#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
+ if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+ {
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
+ }
+#endif
+ return( ret );
+ }
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ if( ssl->conf->badmac_limit != 0 &&
+ ++ssl->badmac_seen >= ssl->conf->badmac_limit )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+#endif
+
+ /* As above, invalid records cause
+ * dismissal of the whole datagram. */
+
+ ssl->next_record_offset = 0;
+ ssl->in_left = 0;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
+ return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+ }
+
+ return( ret );
+ }
+ else
+#endif
+ {
+ /* Error out (and send alert) on invalid records */
+#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
+ if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+ {
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
+ }
+#endif
+ return( ret );
+ }
+ }
+
+
+ /* Reset in pointers to default state for TLS/DTLS records,
+ * assuming no CID and no offset between record content and
+ * record plaintext. */
+ mbedtls_ssl_update_in_pointers( ssl );
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->in_len = ssl->in_cid + rec.cid_len;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->in_iv = ssl->in_len + 2;
+
+ /* The record content type may change during decryption,
+ * so re-read it. */
+ ssl->in_msgtype = rec.type;
+ /* Also update the input buffer, because unfortunately
+ * the server-side ssl_parse_client_hello() reparses the
+ * record header when receiving a ClientHello initiating
+ * a renegotiation. */
+ ssl->in_hdr[0] = rec.type;
+ ssl->in_msg = rec.buf + rec.data_offset;
+ ssl->in_msglen = rec.data_len;
+ MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->in_len, 0 );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ if( ssl->transform_in != NULL &&
+ ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+ {
+ if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
+ return( ret );
+ }
+
+ /* Check actual (decompress) record content length against
+ * configured maximum. */
+ if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+ }
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+
+ return( 0 );
+}
+
+int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /*
+ * Handle particular types of records
+ */
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+ {
+ if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
+ {
+ return( ret );
+ }
+ }
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ if( ssl->in_msglen != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ if( ssl->in_msg[0] != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x",
+ ssl->in_msg[0] ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
+ ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
+ {
+ if( ssl->handshake == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) );
+ return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+ }
+#endif
+ }
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
+ {
+ if( ssl->in_msglen != 2 )
+ {
+ /* Note: Standard allows for more than one 2 byte alert
+ to be packed in a single message, but Mbed TLS doesn't
+ currently support this. */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%u:%u]",
+ ssl->in_msg[0], ssl->in_msg[1] ) );
+
+ /*
+ * Ignore non-fatal alerts, except close_notify and no_renegotiation
+ */
+ if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
+ ssl->in_msg[1] ) );
+ return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
+ }
+
+ if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+ ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
+ return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
+ }
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
+ if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+ ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) );
+ /* Will be handled when trying to parse ServerHello */
+ return( 0 );
+ }
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+ ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
+ /* Will be handled in mbedtls_ssl_parse_certificate() */
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
+
+ /* Silently ignore: fetch new message */
+ return MBEDTLS_ERR_SSL_NON_FATAL;
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Drop unexpected ApplicationData records,
+ * except at the beginning of renegotiations */
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
+ ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+ ssl->state == MBEDTLS_SSL_SERVER_HELLO )
+#endif
+ )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
+ return( MBEDTLS_ERR_SSL_NON_FATAL );
+ }
+
+ if( ssl->handshake != NULL &&
+ ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ return( 0 );
+}
+
+int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
+{
+ return( mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) );
+}
+
+int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
+ unsigned char level,
+ unsigned char message )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ssl == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
+
+ ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
+ ssl->out_msglen = 2;
+ ssl->out_msg[0] = level;
+ ssl->out_msg[1] = message;
+
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+ return( ret );
+ }
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
+
+ return( 0 );
+}
+
+int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
+
+ ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
+ ssl->out_msglen = 1;
+ ssl->out_msg[0] = 1;
+
+ ssl->state++;
+
+ if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+ return( ret );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
+
+ return( 0 );
+}
+
+int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
+
+ if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+ return( ret );
+ }
+
+ if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+
+ /* CCS records are only accepted if they have length 1 and content '1',
+ * so we don't need to check this here. */
+
+ /*
+ * Switch to our negotiated transform and session parameters for inbound
+ * data.
+ */
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
+ ssl->transform_in = ssl->transform_negotiate;
+ ssl->session_in = ssl->session_negotiate;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ mbedtls_ssl_dtls_replay_reset( ssl );
+#endif
+
+ /* Increment epoch */
+ if( ++ssl->in_epoch == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
+ /* This is highly unlikely to happen for legitimate reasons, so
+ treat it as an attack and don't send an alert. */
+ return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ memset( ssl->in_ctr, 0, 8 );
+
+ mbedtls_ssl_update_in_pointers( ssl );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ if( mbedtls_ssl_hw_record_activate != NULL )
+ {
+ if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+ }
+#endif
+
+ ssl->state++;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
+
+ return( 0 );
+}
+
+/* Once ssl->out_hdr as the address of the beginning of the
+ * next outgoing record is set, deduce the other pointers.
+ *
+ * Note: For TLS, we save the implicit record sequence number
+ * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
+ * and the caller has to make sure there's space for this.
+ */
+
+static size_t ssl_transform_get_explicit_iv_len(
+ mbedtls_ssl_transform const *transform )
+{
+ if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
+ return( 0 );
+
+ return( transform->ivlen - transform->fixed_ivlen );
+}
+
+void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->out_ctr = ssl->out_hdr + 3;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->out_cid = ssl->out_ctr + 8;
+ ssl->out_len = ssl->out_cid;
+ if( transform != NULL )
+ ssl->out_len += transform->out_cid_len;
+#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->out_len = ssl->out_ctr + 8;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->out_iv = ssl->out_len + 2;
+ }
+ else
+#endif
+ {
+ ssl->out_ctr = ssl->out_hdr - 8;
+ ssl->out_len = ssl->out_hdr + 3;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->out_cid = ssl->out_len;
+#endif
+ ssl->out_iv = ssl->out_hdr + 5;
+ }
+
+ ssl->out_msg = ssl->out_iv;
+ /* Adjust out_msg to make space for explicit IV, if used. */
+ if( transform != NULL )
+ ssl->out_msg += ssl_transform_get_explicit_iv_len( transform );
+}
+
+/* Once ssl->in_hdr as the address of the beginning of the
+ * next incoming record is set, deduce the other pointers.
+ *
+ * Note: For TLS, we save the implicit record sequence number
+ * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
+ * and the caller has to make sure there's space for this.
+ */
+
+void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl )
+{
+ /* This function sets the pointers to match the case
+ * of unprotected TLS/DTLS records, with both ssl->in_iv
+ * and ssl->in_msg pointing to the beginning of the record
+ * content.
+ *
+ * When decrypting a protected record, ssl->in_msg
+ * will be shifted to point to the beginning of the
+ * record plaintext.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* This sets the header pointers to match records
+ * without CID. When we receive a record containing
+ * a CID, the fields are shifted accordingly in
+ * ssl_parse_record_header(). */
+ ssl->in_ctr = ssl->in_hdr + 3;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->in_cid = ssl->in_ctr + 8;
+ ssl->in_len = ssl->in_cid; /* Default: no CID */
+#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->in_len = ssl->in_ctr + 8;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->in_iv = ssl->in_len + 2;
+ }
+ else
+#endif
+ {
+ ssl->in_ctr = ssl->in_hdr - 8;
+ ssl->in_len = ssl->in_hdr + 3;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->in_cid = ssl->in_len;
+#endif
+ ssl->in_iv = ssl->in_hdr + 5;
+ }
+
+ /* This will be adjusted at record decryption time. */
+ ssl->in_msg = ssl->in_iv;
+}
+
+/*
+ * Setup an SSL context
+ */
+
+void mbedtls_ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
+{
+ /* Set the incoming and outgoing record pointers. */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->out_hdr = ssl->out_buf;
+ ssl->in_hdr = ssl->in_buf;
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ ssl->out_hdr = ssl->out_buf + 8;
+ ssl->in_hdr = ssl->in_buf + 8;
+ }
+
+ /* Derive other internal pointers. */
+ mbedtls_ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
+ mbedtls_ssl_update_in_pointers ( ssl );
+}
+
+/*
+ * SSL get accessors
+ */
+size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
+{
+ return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
+}
+
+int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
+{
+ /*
+ * Case A: We're currently holding back
+ * a message for further processing.
+ */
+
+ if( ssl->keep_current_message == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) );
+ return( 1 );
+ }
+
+ /*
+ * Case B: Further records are pending in the current datagram.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->in_left > ssl->next_record_offset )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
+ return( 1 );
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /*
+ * Case C: A handshake message is being processed.
+ */
+
+ if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) );
+ return( 1 );
+ }
+
+ /*
+ * Case D: An application data message is being processed
+ */
+ if( ssl->in_offt != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) );
+ return( 1 );
+ }
+
+ /*
+ * In all other cases, the rest of the message can be dropped.
+ * As in ssl_get_next_record, this needs to be adapted if
+ * we implement support for multiple alerts in single records.
+ */
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
+ return( 0 );
+}
+
+
+int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
+{
+ size_t transform_expansion = 0;
+ const mbedtls_ssl_transform *transform = ssl->transform_out;
+ unsigned block_size;
+
+ size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl );
+
+ if( transform == NULL )
+ return( (int) out_hdr_len );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
+ switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
+ {
+ case MBEDTLS_MODE_GCM:
+ case MBEDTLS_MODE_CCM:
+ case MBEDTLS_MODE_CHACHAPOLY:
+ case MBEDTLS_MODE_STREAM:
+ transform_expansion = transform->minlen;
+ break;
+
+ case MBEDTLS_MODE_CBC:
+
+ block_size = mbedtls_cipher_get_block_size(
+ &transform->cipher_ctx_enc );
+
+ /* Expansion due to the addition of the MAC. */
+ transform_expansion += transform->maclen;
+
+ /* Expansion due to the addition of CBC padding;
+ * Theoretically up to 256 bytes, but we never use
+ * more than the block size of the underlying cipher. */
+ transform_expansion += block_size;
+
+ /* For TLS 1.1 or higher, an explicit IV is added
+ * after the record header. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ transform_expansion += block_size;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ break;
+
+ default:
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( transform->out_cid_len != 0 )
+ transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ return( (int)( out_hdr_len + transform_expansion ) );
+}
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+/*
+ * Check record counters and renegotiate if they're above the limit.
+ */
+static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
+{
+ size_t ep_len = mbedtls_ssl_ep_len( ssl );
+ int in_ctr_cmp;
+ int out_ctr_cmp;
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
+ ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
+ {
+ return( 0 );
+ }
+
+ in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
+ ssl->conf->renego_period + ep_len, 8 - ep_len );
+ out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
+ ssl->conf->renego_period + ep_len, 8 - ep_len );
+
+ if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
+ {
+ return( 0 );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
+ return( mbedtls_ssl_renegotiate( ssl ) );
+}
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/*
+ * Receive application data decrypted from the SSL layer
+ */
+int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t n;
+
+ if( ssl == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ if( ssl->handshake != NULL &&
+ ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+ {
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ return( ret );
+ }
+ }
+#endif
+
+ /*
+ * Check if renegotiation is necessary and/or handshake is
+ * in process. If yes, perform/continue, and fall through
+ * if an unexpected packet is received while the client
+ * is waiting for the ServerHello.
+ *
+ * (There is no equivalent to the last condition on
+ * the server-side as it is not treated as within
+ * a handshake while waiting for the ClientHello
+ * after a renegotiation request.)
+ */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ ret = ssl_check_ctr_renegotiate( ssl );
+ if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+ return( ret );
+ }
+#endif
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ ret = mbedtls_ssl_handshake( ssl );
+ if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
+ return( ret );
+ }
+ }
+
+ /* Loop as long as no application data record is available */
+ while( ssl->in_offt == NULL )
+ {
+ /* Start timer if not already running */
+ if( ssl->f_get_timer != NULL &&
+ ssl->f_get_timer( ssl->p_timer ) == -1 )
+ {
+ mbedtls_ssl_set_timer( ssl, ssl->conf->read_timeout );
+ }
+
+ if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+ {
+ if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+ return( ret );
+ }
+
+ if( ssl->in_msglen == 0 &&
+ ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
+ {
+ /*
+ * OpenSSL sends empty messages to randomize the IV
+ */
+ if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+ {
+ if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+ return( ret );
+ }
+ }
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
+
+ /*
+ * - For client-side, expect SERVER_HELLO_REQUEST.
+ * - For server-side, expect CLIENT_HELLO.
+ * - Fail (TLS) or silently drop record (DTLS) in other cases.
+ */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+ ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
+ ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
+
+ /* With DTLS, drop the packet (probably from last handshake) */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ continue;
+ }
+#endif
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_SRV_C)
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
+
+ /* With DTLS, drop the packet (probably from last handshake) */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ continue;
+ }
+#endif
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ /* Determine whether renegotiation attempt should be accepted */
+ if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
+ ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+ ssl->conf->allow_legacy_renegotiation ==
+ MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
+ {
+ /*
+ * Accept renegotiation request
+ */
+
+ /* DTLS clients need to know renego is server-initiated */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+ {
+ ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
+ }
+#endif
+ ret = mbedtls_ssl_start_renegotiation( ssl );
+ if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_start_renegotiation",
+ ret );
+ return( ret );
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+ {
+ /*
+ * Refuse renegotiation
+ */
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ /* SSLv3 does not have a "no_renegotiation" warning, so
+ we send a fatal alert and abort the connection. */
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+ {
+ if( ( ret = mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_WARNING,
+ MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
+ {
+ return( ret );
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
+ MBEDTLS_SSL_PROTO_TLS1_2 */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+
+ /* At this point, we don't know whether the renegotiation has been
+ * completed or not. The cases to consider are the following:
+ * 1) The renegotiation is complete. In this case, no new record
+ * has been read yet.
+ * 2) The renegotiation is incomplete because the client received
+ * an application data record while awaiting the ServerHello.
+ * 3) The renegotiation is incomplete because the client received
+ * a non-handshake, non-application data message while awaiting
+ * the ServerHello.
+ * In each of these case, looping will be the proper action:
+ * - For 1), the next iteration will read a new record and check
+ * if it's application data.
+ * - For 2), the loop condition isn't satisfied as application data
+ * is present, hence continue is the same as break
+ * - For 3), the loop condition is satisfied and read_record
+ * will re-deliver the message that was held back by the client
+ * when expecting the ServerHello.
+ */
+ continue;
+ }
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+ {
+ if( ssl->conf->renego_max_records >= 0 )
+ {
+ if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
+ "but not honored by client" ) );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+ }
+ }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+ /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
+ return( MBEDTLS_ERR_SSL_WANT_READ );
+ }
+
+ if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+
+ ssl->in_offt = ssl->in_msg;
+
+ /* We're going to return something now, cancel timer,
+ * except if handshake (renegotiation) is in progress */
+ if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ mbedtls_ssl_set_timer( ssl, 0 );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ /* If we requested renego but received AppData, resend HelloRequest.
+ * Do it now, after setting in_offt, to avoid taking this branch
+ * again if ssl_write_hello_request() returns WANT_WRITE */
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+ {
+ if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request",
+ ret );
+ return( ret );
+ }
+ }
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ }
+
+ n = ( len < ssl->in_msglen )
+ ? len : ssl->in_msglen;
+
+ memcpy( buf, ssl->in_offt, n );
+ ssl->in_msglen -= n;
+
+ /* Zeroising the plaintext buffer to erase unused application data
+ from the memory. */
+ mbedtls_platform_zeroize( ssl->in_offt, n );
+
+ if( ssl->in_msglen == 0 )
+ {
+ /* all bytes consumed */
+ ssl->in_offt = NULL;
+ ssl->keep_current_message = 0;
+ }
+ else
+ {
+ /* more data available */
+ ssl->in_offt += n;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
+
+ return( (int) n );
+}
+
+/*
+ * Send application data to be encrypted by the SSL layer, taking care of max
+ * fragment length and buffer size.
+ *
+ * According to RFC 5246 Section 6.2.1:
+ *
+ * Zero-length fragments of Application data MAY be sent as they are
+ * potentially useful as a traffic analysis countermeasure.
+ *
+ * Therefore, it is possible that the input message length is 0 and the
+ * corresponding return code is 0 on success.
+ */
+static int ssl_write_real( mbedtls_ssl_context *ssl,
+ const unsigned char *buf, size_t len )
+{
+ int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
+ const size_t max_len = (size_t) ret;
+
+ if( ret < 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret );
+ return( ret );
+ }
+
+ if( len > max_len )
+ {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
+ "maximum fragment length: %" MBEDTLS_PRINTF_SIZET
+ " > %" MBEDTLS_PRINTF_SIZET,
+ len, max_len ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ else
+#endif
+ len = max_len;
+ }
+
+ if( ssl->out_left != 0 )
+ {
+ /*
+ * The user has previously tried to send the data and
+ * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
+ * written. In this case, we expect the high-level write function
+ * (e.g. mbedtls_ssl_write()) to be called with the same parameters
+ */
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
+ return( ret );
+ }
+ }
+ else
+ {
+ /*
+ * The user is trying to send a message the first time, so we need to
+ * copy the data into the internal buffers and setup the data structure
+ * to keep track of partial writes
+ */
+ ssl->out_msglen = len;
+ ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
+ memcpy( ssl->out_msg, buf, len );
+
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+ return( ret );
+ }
+ }
+
+ return( (int) len );
+}
+
+/*
+ * Write application data, doing 1/n-1 splitting if necessary.
+ *
+ * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
+ * then the caller will call us again with the same arguments, so
+ * remember whether we already did the split or not.
+ */
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+static int ssl_write_split( mbedtls_ssl_context *ssl,
+ const unsigned char *buf, size_t len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ssl->conf->cbc_record_splitting ==
+ MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
+ len <= 1 ||
+ ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
+ mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
+ != MBEDTLS_MODE_CBC )
+ {
+ return( ssl_write_real( ssl, buf, len ) );
+ }
+
+ if( ssl->split_done == 0 )
+ {
+ if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
+ return( ret );
+ ssl->split_done = 1;
+ }
+
+ if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
+ return( ret );
+ ssl->split_done = 0;
+
+ return( ret + 1 );
+}
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+
+/*
+ * Write application data (public-facing wrapper)
+ */
+int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
+
+ if( ssl == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+ return( ret );
+ }
+#endif
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
+ return( ret );
+ }
+ }
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+ ret = ssl_write_split( ssl, buf, len );
+#else
+ ret = ssl_write_real( ssl, buf, len );
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
+
+ return( ret );
+}
+
+/*
+ * Notify the peer that the connection is being closed
+ */
+int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ssl == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
+
+ if( ssl->out_left != 0 )
+ return( mbedtls_ssl_flush_output( ssl ) );
+
+ if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ if( ( ret = mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_WARNING,
+ MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
+ return( ret );
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
+
+ return( 0 );
+}
+
+void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
+{
+ if( transform == NULL )
+ return;
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ deflateEnd( &transform->ctx_deflate );
+ inflateEnd( &transform->ctx_inflate );
+#endif
+
+ mbedtls_cipher_free( &transform->cipher_ctx_enc );
+ mbedtls_cipher_free( &transform->cipher_ctx_dec );
+
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ mbedtls_md_free( &transform->md_ctx_enc );
+ mbedtls_md_free( &transform->md_ctx_dec );
+#endif
+
+ mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl )
+{
+ unsigned offset;
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+ if( hs == NULL )
+ return;
+
+ ssl_free_buffered_record( ssl );
+
+ for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
+ ssl_buffering_free_slot( ssl, offset );
+}
+
+static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
+ uint8_t slot )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
+
+ if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS )
+ return;
+
+ if( hs_buf->is_valid == 1 )
+ {
+ hs->buffering.total_bytes_buffered -= hs_buf->data_len;
+ mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len );
+ mbedtls_free( hs_buf->data );
+ memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
+ }
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+/*
+ * Convert version numbers to/from wire format
+ * and, for DTLS, to/from TLS equivalent.
+ *
+ * For TLS this is the identity.
+ * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
+ * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1)
+ * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
+ */
+void mbedtls_ssl_write_version( int major, int minor, int transport,
+ unsigned char ver[2] )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
+ --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
+
+ ver[0] = (unsigned char)( 255 - ( major - 2 ) );
+ ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
+ }
+ else
+#else
+ ((void) transport);
+#endif
+ {
+ ver[0] = (unsigned char) major;
+ ver[1] = (unsigned char) minor;
+ }
+}
+
+void mbedtls_ssl_read_version( int *major, int *minor, int transport,
+ const unsigned char ver[2] )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ *major = 255 - ver[0] + 2;
+ *minor = 255 - ver[1] + 1;
+
+ if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
+ ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
+ }
+ else
+#else
+ ((void) transport);
+#endif
+ {
+ *major = ver[0];
+ *minor = ver[1];
+ }
+}
+
+#endif /* MBEDTLS_SSL_TLS_C */
diff --git a/thirdparty/mbedtls/library/ssl_srv.c b/thirdparty/mbedtls/library/ssl_srv.c
index cbf6142ac2..1a63173204 100644
--- a/thirdparty/mbedtls/library/ssl_srv.c
+++ b/thirdparty/mbedtls/library/ssl_srv.c
@@ -2,13 +2,7 @@
* SSLv3/TLSv1 server-side functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_SRV_C)
@@ -60,10 +29,13 @@
#define mbedtls_free free
#endif
-#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
@@ -110,7 +82,7 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t servername_list_size, hostname_len;
const unsigned char *p;
@@ -174,6 +146,48 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf )
+{
+ if( conf->f_psk != NULL )
+ return( 1 );
+
+ if( conf->psk_identity_len == 0 || conf->psk_identity == NULL )
+ return( 0 );
+
+ if( conf->psk != NULL && conf->psk_len != 0 )
+ return( 1 );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
+ return( 1 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
+{
+ if( ssl->conf->f_psk != NULL )
+ {
+ /* If we've used a callback to select the PSK,
+ * the static configuration is irrelevant. */
+
+ if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+ return( 1 );
+
+ return( 0 );
+ }
+
+ if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
+ return( 1 );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+
static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -184,7 +198,7 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
/* Check verify-data in constant-time. The length OTOH is no secret */
if( len != 1 + ssl->verify_data_len ||
buf[0] != ssl->verify_data_len ||
- mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data,
+ mbedtls_ct_memcmp( buf + 1, ssl->peer_verify_data,
ssl->verify_data_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -211,7 +225,7 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Status of the implementation of signature-algorithms extension:
@@ -286,20 +300,20 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
{
mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:"
- " match sig %d and hash %d",
- sig_cur, md_cur ) );
+ " match sig %u and hash %u",
+ (unsigned) sig_cur, (unsigned) md_cur ) );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: "
- "hash alg %d not supported", md_cur ) );
+ "hash alg %u not supported", (unsigned) md_cur ) );
}
}
return( 0 );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -415,7 +429,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
{
@@ -458,6 +472,78 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ size_t peer_cid_len;
+
+ /* CID extension only makes sense in DTLS */
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ /*
+ * Quoting draft-ietf-tls-dtls-connection-id-05
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
+ *
+ * struct {
+ * opaque cid<0..2^8-1>;
+ * } ConnectionId;
+ */
+
+ if( len < 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ peer_cid_len = *buf++;
+ len--;
+
+ if( len != peer_cid_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ /* Ignore CID if the user has disabled its use. */
+ if( ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
+ {
+ /* Leave ssl->handshake->cid_in_use in its default
+ * value of MBEDTLS_SSL_CID_DISABLED. */
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Client sent CID extension, but CID disabled" ) );
+ return( 0 );
+ }
+
+ if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
+ ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len;
+ memcpy( ssl->handshake->peer_cid, buf, peer_cid_len );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Client CID", buf, peer_cid_len );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
@@ -535,7 +621,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_session session;
mbedtls_ssl_session_init( &session );
@@ -549,7 +635,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
/* Remember the client asked us to send a new ticket */
ssl->handshake->new_session_ticket = 1;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %" MBEDTLS_PRINTF_SIZET, len ) );
if( len == 0 )
return( 0 );
@@ -692,6 +778,126 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET;
+ size_t i,j;
+ size_t profile_length;
+ uint16_t mki_length;
+ /*! 2 bytes for profile length and 1 byte for mki len */
+ const size_t size_of_lengths = 3;
+
+ /* If use_srtp is not configured, just ignore the extension */
+ if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+ ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+ ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+ {
+ return( 0 );
+ }
+
+ /* RFC5764 section 4.1.1
+ * uint8 SRTPProtectionProfile[2];
+ *
+ * struct {
+ * SRTPProtectionProfiles SRTPProtectionProfiles;
+ * opaque srtp_mki<0..255>;
+ * } UseSRTPData;
+
+ * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+ */
+
+ /*
+ * Min length is 5: at least one protection profile(2 bytes)
+ * and length(2 bytes) + srtp_mki length(1 byte)
+ * Check here that we have at least 2 bytes of protection profiles length
+ * and one of srtp_mki length
+ */
+ if( len < size_of_lengths )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
+
+ /* first 2 bytes are protection profile length(in bytes) */
+ profile_length = ( buf[0] << 8 ) | buf[1];
+ buf += 2;
+
+ /* The profile length cannot be bigger than input buffer size - lengths fields */
+ if( profile_length > len - size_of_lengths ||
+ profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+ /*
+ * parse the extension list values are defined in
+ * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+ */
+ for( j = 0; j < profile_length; j += 2 )
+ {
+ uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1];
+ client_protection = mbedtls_ssl_check_srtp_profile_value( protection_profile_value );
+
+ if( client_protection != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s",
+ mbedtls_ssl_get_srtp_profile_as_string(
+ client_protection ) ) );
+ }
+ else
+ {
+ continue;
+ }
+ /* check if suggested profile is in our list */
+ for( i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
+ {
+ if( client_protection == ssl->conf->dtls_srtp_profile_list[i] )
+ {
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
+ mbedtls_ssl_get_srtp_profile_as_string(
+ client_protection ) ) );
+ break;
+ }
+ }
+ if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET )
+ break;
+ }
+ buf += profile_length; /* buf points to the mki length */
+ mki_length = *buf;
+ buf++;
+
+ if( mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ||
+ mki_length + profile_length + size_of_lengths != len )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ /* Parse the mki only if present and mki is supported locally */
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
+ mki_length > 0 )
+ {
+ ssl->dtls_srtp_info.mki_len = mki_length;
+
+ memcpy( ssl->dtls_srtp_info.mki_value, buf, mki_length );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "using mki", ssl->dtls_srtp_info.mki_value,
+ ssl->dtls_srtp_info.mki_len );
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/*
* Auxiliary functions for ServerHello parsing and related actions
*/
@@ -750,6 +956,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
for( cur = list; cur != NULL; cur = cur->next )
{
+ flags = 0;
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
cur->cert );
@@ -831,7 +1038,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
const mbedtls_ssl_ciphersuite_t *suite_info;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
mbedtls_pk_type_t sig_type;
#endif
@@ -842,7 +1049,8 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %#04x (%s)",
+ (unsigned int) suite_id, suite_info->name ) );
if( suite_info->min_minor_ver > ssl->minor_ver ||
suite_info->max_minor_ver < ssl->minor_ver )
@@ -888,13 +1096,11 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
}
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
/* If the ciphersuite requires a pre-shared key and we don't
* have one, skip it now rather than failing later */
if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
- ssl->conf->f_psk == NULL &&
- ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
- ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
+ ssl_conf_has_psk_or_cb( ssl->conf ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) );
return( 0 );
@@ -902,7 +1108,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/* If the ciphersuite requires signing, check whether
* a suitable hash algorithm is present. */
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
@@ -912,13 +1118,13 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm "
- "for signature algorithm %d", sig_type ) );
+ "for signature algorithm %u", (unsigned) sig_type ) );
return( 0 );
}
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/*
@@ -1043,7 +1249,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
sess_len = ( buf[2] << 8 ) | buf[3];
chal_len = ( buf[4] << 8 ) | buf[5];
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d",
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %u, sess_len: %u, chal_len: %u",
ciph_len, sess_len, chal_len ) );
/*
@@ -1118,8 +1324,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
{
if( p[0] == 0 &&
- p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
- p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) )
+ MBEDTLS_GET_UINT16_BE(p, 1) != MBEDTLS_SSL_FALLBACK_SCSV_VALUE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) );
@@ -1150,8 +1355,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
#endif
{
if( p[0] != 0 ||
- p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
- p[2] != ( ( ciphersuites[i] ) & 0xFF ) )
+ MBEDTLS_GET_UINT16_BE(p, 1) != ciphersuites[i] )
continue;
got_common_suite = 1;
@@ -1180,7 +1384,7 @@ have_ciphersuite_v2:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
ssl->session_negotiate->ciphersuite = ciphersuites[i];
- ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
+ ssl->handshake->ciphersuite_info = ciphersuite_info;
/*
* SSLv2 Client Hello relevant renegotiation security checks
@@ -1228,10 +1432,10 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
* we need to fall back to the default values for allowed
* signature-hash pairs. */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
int sig_hash_alg_ext_present = 0;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
@@ -1265,7 +1469,7 @@ read_record_header:
return( ssl_parse_client_hello_v2( ssl ) );
#endif
- MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_in_hdr_len( ssl ) );
/*
* SSLv3/TLS Client Hello
@@ -1354,7 +1558,7 @@ read_record_header:
}
if( ( ret = mbedtls_ssl_fetch_input( ssl,
- mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 )
+ mbedtls_ssl_in_hdr_len( ssl ) + msg_len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
return( ret );
@@ -1363,7 +1567,7 @@ read_record_header:
/* Done reading this record, get ready for the next one */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl );
+ ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len( ssl );
else
#endif
ssl->in_left = 0;
@@ -1425,7 +1629,7 @@ read_record_header:
if( cli_msg_seq != ssl->handshake->in_msg_seq )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: "
- "%d (expected %d)", cli_msg_seq,
+ "%u (expected %u)", cli_msg_seq,
ssl->handshake->in_msg_seq ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
@@ -1683,8 +1887,7 @@ read_record_header:
ext_len = ( buf[ext_offset + 0] << 8 )
| ( buf[ext_offset + 1] );
- if( ( ext_len > 0 && ext_len < 4 ) ||
- msg_len != ext_offset + 2 + ext_len )
+ if( msg_len != ext_offset + 2 + ext_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@@ -1744,7 +1947,7 @@ read_record_header:
break;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
case MBEDTLS_TLS_EXT_SIG_ALG:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
@@ -1755,7 +1958,7 @@ read_record_header:
sig_hash_alg_ext_present = 1;
break;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1808,6 +2011,16 @@ read_record_header:
break;
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ case MBEDTLS_TLS_EXT_CID:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) );
+
+ ret = ssl_parse_cid_ext( ssl, ext + 4, ext_size );
+ if( ret != 0 )
+ return( ret );
+ break;
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
@@ -1848,21 +2061,23 @@ read_record_header:
break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ case MBEDTLS_TLS_EXT_USE_SRTP:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+
+ ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
+ if( ret != 0 )
+ return( ret );
+ break;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
default:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %u (ignoring)",
ext_id ) );
}
ext_len -= 4 + ext_size;
ext += 4 + ext_size;
-
- if( ext_len > 0 && ext_len < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
}
@@ -1871,8 +2086,7 @@ read_record_header:
#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 )
{
- if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
- p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) )
+ if( MBEDTLS_GET_UINT16_BE( p, 0 ) == MBEDTLS_SSL_FALLBACK_SCSV_VALUE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) );
@@ -1892,7 +2106,7 @@ read_record_header:
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Try to fall back to default hash SHA1 if the client
@@ -1909,7 +2123,7 @@ read_record_header:
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/*
* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
@@ -1990,8 +2204,7 @@ read_record_header:
for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
#endif
{
- if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
- p[1] != ( ( ciphersuites[i] ) & 0xFF ) )
+ if( MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i] )
continue;
got_common_suite = 1;
@@ -2024,7 +2237,7 @@ have_ciphersuite:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
ssl->session_negotiate->ciphersuite = ciphersuites[i];
- ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
+ ssl->handshake->ciphersuite_info = ciphersuite_info;
ssl->state++;
@@ -2036,7 +2249,7 @@ have_ciphersuite:
/* Debugging-only output for testsuite */
#if defined(MBEDTLS_DEBUG_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info );
@@ -2050,7 +2263,7 @@ have_ciphersuite:
else
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm "
- "%d - should not happen", sig_alg ) );
+ "%u - should not happen", (unsigned) sig_alg ) );
}
}
#endif
@@ -2075,8 +2288,8 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_TRUNCATED_HMAC, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -2085,6 +2298,53 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+static void ssl_write_cid_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t ext_len;
+ const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+ *olen = 0;
+
+ /* Skip writing the extension if we don't want to use it or if
+ * the client hasn't offered it. */
+ if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED )
+ return;
+
+ /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
+ * which is at most 255, so the increment cannot overflow. */
+ if( end < p || (size_t)( end - p ) < (unsigned)( ssl->own_cid_len + 5 ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+ return;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding CID extension" ) );
+
+ /*
+ * Quoting draft-ietf-tls-dtls-connection-id-05
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
+ *
+ * struct {
+ * opaque cid<0..2^8-1>;
+ * } ConnectionId;
+ */
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_CID, p, 0 );
+ p += 2;
+ ext_len = (size_t) ssl->own_cid_len + 1;
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2;
+
+ *p++ = (uint8_t) ssl->own_cid_len;
+ memcpy( p, ssl->own_cid, ssl->own_cid_len );
+
+ *olen = ssl->own_cid_len + 5;
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
@@ -2118,8 +2378,8 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -2145,8 +2405,8 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret "
"extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -2170,8 +2430,8 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -2194,8 +2454,8 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0 );
+ p += 2;
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
@@ -2235,8 +2495,8 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 1;
@@ -2265,8 +2525,8 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 2;
@@ -2283,7 +2543,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
size_t kkpp_len;
@@ -2291,7 +2551,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
*olen = 0;
/* Skip costly computation if not needed */
- if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
+ if( ssl->handshake->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
return;
@@ -2303,8 +2563,8 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
return;
}
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 );
+ p += 2;
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
@@ -2315,8 +2575,8 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
return;
}
- *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 );
+ p += 2;
*olen = kkpp_len + 4;
}
@@ -2341,27 +2601,93 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
* 6 . 6 protocol name length
* 7 . 7+n protocol name
*/
- buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
- buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ALPN, buf, 0);
*olen = 7 + strlen( ssl->alpn_chosen );
- buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
- buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( *olen - 4, buf, 2 );
- buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
- buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( *olen - 6, buf, 4 );
- buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF );
+ buf[6] = MBEDTLS_BYTE_0( *olen - 7 );
memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 );
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
+#if defined(MBEDTLS_SSL_DTLS_SRTP ) && defined(MBEDTLS_SSL_PROTO_DTLS)
+static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ size_t *olen )
+{
+ size_t mki_len = 0, ext_len = 0;
+ uint16_t profile_value = 0;
+ const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+ *olen = 0;
+
+ if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+ ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) )
+ {
+ return;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) );
+
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+ {
+ mki_len = ssl->dtls_srtp_info.mki_len;
+ }
+
+ /* The extension total size is 9 bytes :
+ * - 2 bytes for the extension tag
+ * - 2 bytes for the total size
+ * - 2 bytes for the protection profile length
+ * - 2 bytes for the protection profile
+ * - 1 byte for the mki length
+ * + the actual mki length
+ * Check we have enough room in the output buffer */
+ if( (size_t)( end - buf ) < mki_len + 9 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+ return;
+ }
+
+ /* extension */
+ MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0 );
+ /*
+ * total length 5 and mki value: only one profile(2 bytes)
+ * and length(2 bytes) and srtp_mki )
+ */
+ ext_len = 5 + mki_len;
+ MBEDTLS_PUT_UINT16_BE( ext_len, buf, 2 );
+
+ /* protection profile length: 2 */
+ buf[4] = 0x00;
+ buf[5] = 0x02;
+ profile_value = mbedtls_ssl_check_srtp_profile_value(
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
+ if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ MBEDTLS_PUT_UINT16_BE( profile_value, buf, 6 );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "use_srtp extension invalid profile" ) );
+ return;
+ }
+
+ buf[8] = mki_len & 0xFF;
+ memcpy( &buf[9], ssl->dtls_srtp_info.mki_value, mki_len );
+
+ *olen = 9 + mki_len;
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = ssl->out_msg + 4;
unsigned char *cookie_len_byte;
@@ -2430,12 +2756,61 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
}
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+static void ssl_handle_id_based_session_resumption( mbedtls_ssl_context *ssl )
+{
+ int ret;
+ mbedtls_ssl_session session_tmp;
+ mbedtls_ssl_session * const session = ssl->session_negotiate;
+
+ /* Resume is 0 by default, see ssl_handshake_init().
+ * It may be already set to 1 by ssl_parse_session_ticket_ext(). */
+ if( ssl->handshake->resume == 1 )
+ return;
+ if( session->id_len == 0 )
+ return;
+ if( ssl->conf->f_get_cache == NULL )
+ return;
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+ return;
+#endif
+
+ mbedtls_ssl_session_init( &session_tmp );
+
+ session_tmp.id_len = session->id_len;
+ memcpy( session_tmp.id, session->id, session->id_len );
+
+ ret = ssl->conf->f_get_cache( ssl->conf->p_cache,
+ &session_tmp );
+ if( ret != 0 )
+ goto exit;
+
+ if( session->ciphersuite != session_tmp.ciphersuite ||
+ session->compression != session_tmp.compression )
+ {
+ /* Mismatch between cached and negotiated session */
+ goto exit;
+ }
+
+ /* Move semantics */
+ mbedtls_ssl_session_free( session );
+ *session = session_tmp;
+ memset( &session_tmp, 0, sizeof( session_tmp ) );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
+ ssl->handshake->resume = 1;
+
+exit:
+
+ mbedtls_ssl_session_free( &session_tmp );
+}
+
static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t t;
#endif
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen, ext_len = 0, n;
unsigned char *buf, *p;
@@ -2477,12 +2852,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_HAVE_TIME)
t = mbedtls_time( NULL );
- *p++ = (unsigned char)( t >> 24 );
- *p++ = (unsigned char)( t >> 16 );
- *p++ = (unsigned char)( t >> 8 );
- *p++ = (unsigned char)( t );
+ MBEDTLS_PUT_UINT32_BE( t, p, 0 );
+ p += 4;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
+ (long long) t ) );
#else
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
return( ret );
@@ -2499,22 +2873,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
- /*
- * Resume is 0 by default, see ssl_handshake_init().
- * It may be already set to 1 by ssl_parse_session_ticket_ext().
- * If not, try looking up session ID in our cache.
- */
- if( ssl->handshake->resume == 0 &&
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE &&
-#endif
- ssl->session_negotiate->id_len != 0 &&
- ssl->conf->f_get_cache != NULL &&
- ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
- ssl->handshake->resume = 1;
- }
+ ssl_handle_id_based_session_resumption( ssl );
if( ssl->handshake->resume == 0 )
{
@@ -2570,19 +2929,19 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len );
p += ssl->session_negotiate->id_len;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->handshake->resume ? "a" : "no" ) );
- *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 );
- *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite );
- *p++ = (unsigned char)( ssl->session_negotiate->compression );
+ MBEDTLS_PUT_UINT16_BE( ssl->session_negotiate->ciphersuite, p, 0 );
+ p += 2;
+ *p++ = MBEDTLS_BYTE_0( ssl->session_negotiate->compression );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s",
mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X",
- ssl->session_negotiate->compression ) );
+ (unsigned int) ssl->session_negotiate->compression ) );
/* Do not write the extensions if the protocol is SSLv3 */
#if defined(MBEDTLS_SSL_PROTO_SSL3)
@@ -2606,6 +2965,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen );
+ ext_len += olen;
+#endif
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
@@ -2641,13 +3005,18 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
+ ext_len += olen;
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
+ ext_len ) );
if( ext_len > 0 )
{
- *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ext_len ) & 0xFF );
- p += ext_len;
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2 + ext_len;
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
@@ -2665,24 +3034,15 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
return( ret );
}
-#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
ssl->state++;
@@ -2692,13 +3052,13 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else
+#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
- size_t dn_size, total_dn_size; /* excluding length bytes */
+ ssl->handshake->ciphersuite_info;
+ uint16_t dn_size, total_dn_size; /* excluding length bytes */
size_t ct_len, sa_len; /* including length bytes */
unsigned char *buf, *p;
const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
@@ -2716,11 +3076,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
#endif
authmode = ssl->conf->authmode;
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ||
authmode == MBEDTLS_SSL_VERIFY_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
@@ -2799,8 +3155,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
#endif
}
- p[0] = (unsigned char)( sa_len >> 8 );
- p[1] = (unsigned char)( sa_len );
+ MBEDTLS_PUT_UINT16_BE( sa_len, p, 0 );
sa_len += 2;
p += sa_len;
}
@@ -2816,6 +3171,11 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED )
{
+ /* NOTE: If trusted certificates are provisioned
+ * via a CA callback (configured through
+ * `mbedtls_ssl_conf_ca_cb()`, then the
+ * CertificateRequest is currently left empty. */
+
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
if( ssl->handshake->sni_ca_chain != NULL )
crt = ssl->handshake->sni_ca_chain;
@@ -2825,18 +3185,18 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
while( crt != NULL && crt->version != 0 )
{
- dn_size = crt->subject_raw.len;
+ /* It follows from RFC 5280 A.1 that this length
+ * can be represented in at most 11 bits. */
+ dn_size = (uint16_t) crt->subject_raw.len;
- if( end < p ||
- (size_t)( end - p ) < dn_size ||
- (size_t)( end - p ) < 2 + dn_size )
+ if( end < p || (size_t)( end - p ) < 2 + (size_t) dn_size )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) );
break;
}
- *p++ = (unsigned char)( dn_size >> 8 );
- *p++ = (unsigned char)( dn_size );
+ MBEDTLS_PUT_UINT16_BE( dn_size, p, 0 );
+ p += 2;
memcpy( p, crt->subject_raw.p, dn_size );
p += dn_size;
@@ -2850,8 +3210,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
ssl->out_msglen = p - buf;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
- ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 );
- ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size );
+ MBEDTLS_PUT_UINT16_BE( total_dn_size, ssl->out_msg, 4 + ct_len + sa_len );
ret = mbedtls_ssl_write_handshake_msg( ssl );
@@ -2859,18 +3218,13 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
return( ret );
}
-#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) )
{
@@ -2891,7 +3245,7 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
@@ -2914,7 +3268,7 @@ static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret );
return( ret );
}
-#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
/* Prepare the ServerKeyExchange message, up to and including
@@ -2924,17 +3278,18 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+ ssl->handshake->ciphersuite_info;
+
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
unsigned char *dig_signed = NULL;
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
(void) ciphersuite_info; /* unused in some configurations */
-#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
(void) signature_len;
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
@@ -2950,7 +3305,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
ret = mbedtls_ecjpake_write_round_two(
@@ -2987,10 +3342,10 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
/*
* - DHE key exchanges
*/
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
@@ -3026,7 +3381,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
return( ret );
}
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
dig_signed = ssl->out_msg + ssl->out_msglen;
#endif
@@ -3037,12 +3392,12 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */
/*
* - ECDHE key exchanges
*/
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) )
{
/*
@@ -3055,7 +3410,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
*/
const mbedtls_ecp_curve_info **curve = NULL;
const mbedtls_ecp_group_id *gid;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
/* Match our preference list against the offered curves */
@@ -3090,7 +3445,7 @@ curve_matching_done:
return( ret );
}
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
dig_signed = ssl->out_msg + ssl->out_msglen;
#endif
@@ -3099,7 +3454,7 @@ curve_matching_done:
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Q );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */
/*
*
@@ -3107,13 +3462,17 @@ curve_matching_done:
* exchange parameters, compute and add the signature here.
*
*/
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
{
size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
size_t hashlen = 0;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ unsigned char hash[PSA_HASH_MAX_SIZE];
+#else
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
- int ret;
+#endif
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/*
* 2.1: Choose hash algorithm:
@@ -3160,7 +3519,7 @@ curve_matching_done:
md_alg = MBEDTLS_MD_NONE;
}
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %u for signing", (unsigned) md_alg ) );
/*
* 2.2: Compute the hash to be signed
@@ -3275,7 +3634,7 @@ curve_matching_done:
return( ret );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
return( 0 );
}
@@ -3286,28 +3645,28 @@ curve_matching_done:
* machine. */
static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t signature_len = 0;
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+ ssl->handshake->ciphersuite_info;
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
/* Extract static ECDH parameters and abort if ServerKeyExchange
* is not needed. */
if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
{
/* For suites involving ECDH, extract DH parameters
* from certificate at this point. */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
{
ssl_get_ecdh_params_from_cert( ssl );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
/* Key exchanges not involving ephemeral keys don't use
* ServerKeyExchange, so end here. */
@@ -3315,9 +3674,9 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
ssl->state++;
return( 0 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
/* If we have already prepared the message and there is an ongoing
* signature operation, resume signing. */
@@ -3327,7 +3686,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
ret = ssl_resume_server_key_exchange( ssl, &signature_len );
}
else
-#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
{
/* ServerKeyExchange is needed. Prepare the message. */
@@ -3350,11 +3709,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
/* If there is a signature, write its length.
* ssl_prepare_server_key_exchange already wrote the signature
* itself at its proper place in the output buffer. */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
if( signature_len != 0 )
{
- ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
- ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len );
+ ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1( signature_len );
+ ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0( signature_len );
MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
ssl->out_msg + ssl->out_msglen,
@@ -3363,7 +3722,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
/* Skip over the already-written signature */
ssl->out_msglen += signature_len;
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
/* Add header and send. */
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@@ -3383,7 +3742,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) );
@@ -3487,7 +3846,7 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
size_t *peer_pmslen,
size_t peer_pmssize )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk;
size_t len = mbedtls_pk_get_len( public_key );
@@ -3510,12 +3869,13 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
{
- if ( p + 2 > end ) {
+ if ( p + 2 > end )
+ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
- if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
- *p++ != ( ( len ) & 0xFF ) )
+ if( *p++ != MBEDTLS_BYTE_1( len ) ||
+ *p++ != MBEDTLS_BYTE_0( len ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
@@ -3576,7 +3936,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
const unsigned char *end,
size_t pms_offset )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *pms = ssl->handshake->premaster + pms_offset;
unsigned char ver[2];
unsigned char fake_pms[48], peer_pms[48];
@@ -3617,16 +3977,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
diff |= peer_pms[1] ^ ver[1];
/* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
- /* 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
- mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
+ mask = mbedtls_ct_uint_mask( diff );
/*
* Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
@@ -3668,16 +4019,14 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p,
const unsigned char *end )
{
int ret = 0;
- size_t n;
+ uint16_t n;
- if( ssl->conf->f_psk == NULL &&
- ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
- ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
+ if( ssl_conf_has_psk_or_cb( ssl->conf ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) );
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
@@ -3695,7 +4044,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
n = ( (*p)[0] << 8 ) | (*p)[1];
*p += 2;
- if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) )
+ if( n == 0 || n > end - *p )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
@@ -3711,7 +4060,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
/* Identity is not a big secret since clients send it in the clear,
* but treat it carefully anyway, just in case */
if( n != ssl->conf->psk_identity_len ||
- mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
+ mbedtls_ct_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
{
ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
}
@@ -3729,15 +4078,15 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
return( 0 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
unsigned char *p, *end;
- ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+ ciphersuite_info = ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
@@ -3857,6 +4206,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* For opaque PSKs, we perform the PSK-to-MS derivation atomatically
+ * and skip the intermediate PMS. */
+ if( ssl_use_opaque_psk( ssl ) == 1 )
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) );
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
ciphersuite_info->key_exchange ) ) != 0 )
{
@@ -3888,6 +4244,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only. */
+ if( ssl_use_opaque_psk( ssl ) == 1 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret );
@@ -3917,6 +4279,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only. */
+ if( ssl_use_opaque_psk( ssl ) == 1 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
if( p != end )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
@@ -3948,6 +4316,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only. */
+ if( ssl_use_opaque_psk( ssl ) == 1 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_QP );
@@ -4011,24 +4385,15 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( 0 );
}
-#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
@@ -4038,7 +4403,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else
+#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -4051,21 +4416,33 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
#endif
mbedtls_md_type_t md_alg;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
+ mbedtls_pk_context * peer_pk;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
- ssl->session_negotiate->peer_cert == NULL )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
+ ssl->state++;
+ return( 0 );
+ }
+
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if( ssl->session_negotiate->peer_cert == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
+ ssl->state++;
+ return( 0 );
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( ssl->session_negotiate->peer_cert_digest == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
return( 0 );
}
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/* Read the message without adding it to the checksum */
ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ );
@@ -4087,6 +4464,17 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
i = mbedtls_ssl_hs_hdr_len( ssl );
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( ssl->session_negotiate->peer_cert == NULL )
+ {
+ /* Should never happen */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
/*
* struct {
* SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
@@ -4101,8 +4489,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
hashlen = 36;
/* For ECDSA, use SHA-1, not MD-5 + SHA-1 */
- if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_ECDSA ) )
+ if( mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECDSA ) )
{
hash_start += 16;
hashlen -= 16;
@@ -4157,7 +4544,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
/*
* Check the certificate's key type matches the signature alg
*/
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
+ if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
@@ -4188,9 +4575,12 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
}
/* Calculate hash and verify signature */
- ssl->handshake->calc_verify( ssl, hash );
+ {
+ size_t dummy_hlen;
+ ssl->handshake->calc_verify( ssl, hash, &dummy_hlen );
+ }
- if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
+ if( ( ret = mbedtls_pk_verify( peer_pk,
md_alg, hash_start, hashlen,
ssl->in_msg + i, sig_len ) ) != 0 )
{
@@ -4204,17 +4594,12 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
-#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t tlen;
uint32_t lifetime;
@@ -4244,14 +4629,8 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
tlen = 0;
}
- ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF;
- ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF;
- ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF;
- ssl->out_msg[7] = ( lifetime ) & 0xFF;
-
- ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF );
- ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF );
-
+ MBEDTLS_PUT_UINT32_BE( lifetime, ssl->out_msg, 4 );
+ MBEDTLS_PUT_UINT16_BE( tlen, ssl->out_msg, 8 );
ssl->out_msglen = 10 + tlen;
/*
diff --git a/thirdparty/mbedtls/library/ssl_ticket.c b/thirdparty/mbedtls/library/ssl_ticket.c
index bbde8e4ceb..046ed1b2ff 100644
--- a/thirdparty/mbedtls/library/ssl_ticket.c
+++ b/thirdparty/mbedtls/library/ssl_ticket.c
@@ -2,13 +2,7 @@
* TLS server tickets callbacks implementation
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_TICKET_C)
@@ -62,6 +31,7 @@
#include "mbedtls/ssl_internal.h"
#include "mbedtls/ssl_ticket.h"
+#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include <string.h>
@@ -99,7 +69,7 @@ void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx )
static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx,
unsigned char index )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[MAX_KEY_BYTES];
mbedtls_ssl_ticket_key *key = ctx->keys + index;
@@ -159,7 +129,7 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
mbedtls_cipher_type_t cipher,
uint32_t lifetime )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
ctx->f_rng = f_rng;
@@ -180,11 +150,27 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 ||
- ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 )
- {
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ret = mbedtls_cipher_setup_psa( &ctx->keys[0].ctx,
+ cipher_info, TICKET_AUTH_TAG_BYTES );
+ if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+ return( ret );
+ /* We don't yet expect to support all ciphers through PSA,
+ * so allow fallback to ordinary mbedtls_cipher_setup(). */
+ if( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 )
+ return( ret );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ret = mbedtls_cipher_setup_psa( &ctx->keys[1].ctx,
+ cipher_info, TICKET_AUTH_TAG_BYTES );
+ if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+ return( ret );
+ if( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ if( ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 )
return( ret );
- }
if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 ||
( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 )
@@ -196,115 +182,6 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
}
/*
- * Serialize a session in the following format:
- * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
- * n . n+2 peer_cert length = m (0 if no certificate)
- * n+3 . n+2+m peer cert ASN.1
- */
-static int ssl_save_session( const mbedtls_ssl_session *session,
- unsigned char *buf, size_t buf_len,
- size_t *olen )
-{
- unsigned char *p = buf;
- size_t left = buf_len;
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- size_t cert_len;
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- if( left < sizeof( mbedtls_ssl_session ) )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-
- memcpy( p, session, sizeof( mbedtls_ssl_session ) );
- p += sizeof( mbedtls_ssl_session );
- left -= sizeof( mbedtls_ssl_session );
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( session->peer_cert == NULL )
- cert_len = 0;
- else
- cert_len = session->peer_cert->raw.len;
-
- 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 );
-
- if( session->peer_cert != NULL )
- memcpy( p, session->peer_cert->raw.p, cert_len );
-
- p += cert_len;
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- *olen = p - buf;
-
- return( 0 );
-}
-
-/*
- * Unserialise session, see ssl_save_session()
- */
-static int ssl_load_session( mbedtls_ssl_session *session,
- const unsigned char *buf, size_t len )
-{
- const unsigned char *p = buf;
- const unsigned char * const end = buf + len;
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- size_t cert_len;
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- 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( 3 > (size_t)( end - p ) )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
- p += 3;
-
- if( cert_len == 0 )
- {
- session->peer_cert = NULL;
- }
- else
- {
- int ret;
-
- if( cert_len > (size_t)( end - p ) )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
-
- if( session->peer_cert == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
-
- mbedtls_x509_crt_init( session->peer_cert );
-
- if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
- p, cert_len ) ) != 0 )
- {
- mbedtls_x509_crt_free( session->peer_cert );
- mbedtls_free( session->peer_cert );
- session->peer_cert = NULL;
- return( ret );
- }
-
- p += cert_len;
- }
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- if( p != end )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- return( 0 );
-}
-
-/*
* Create session ticket, with the following structure:
*
* struct {
@@ -325,14 +202,13 @@ int mbedtls_ssl_ticket_write( void *p_ticket,
size_t *tlen,
uint32_t *ticket_lifetime )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_ticket_context *ctx = p_ticket;
mbedtls_ssl_ticket_key *key;
unsigned char *key_name = start;
unsigned char *iv = start + TICKET_KEY_NAME_BYTES;
unsigned char *state_len_bytes = iv + TICKET_IV_BYTES;
unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES;
- unsigned char *tag;
size_t clear_len, ciph_len;
*tlen = 0;
@@ -362,33 +238,33 @@ int mbedtls_ssl_ticket_write( void *p_ticket,
goto cleanup;
/* Dump session state */
- if( ( ret = ssl_save_session( session,
- state, end - state, &clear_len ) ) != 0 ||
+ if( ( ret = mbedtls_ssl_session_save( session,
+ state, end - state,
+ &clear_len ) ) != 0 ||
(unsigned long) clear_len > 65535 )
{
goto cleanup;
}
- state_len_bytes[0] = ( clear_len >> 8 ) & 0xff;
- state_len_bytes[1] = ( clear_len ) & 0xff;
+ MBEDTLS_PUT_UINT16_BE( clear_len, state_len_bytes, 0 );
/* Encrypt and authenticate */
- tag = state + clear_len;
- if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx,
+ if( ( ret = mbedtls_cipher_auth_encrypt_ext( &key->ctx,
iv, TICKET_IV_BYTES,
/* Additional data: key name, IV and length */
key_name, TICKET_ADD_DATA_LEN,
- state, clear_len, state, &ciph_len,
- tag, TICKET_AUTH_TAG_BYTES ) ) != 0 )
+ state, clear_len,
+ state, end - state, &ciph_len,
+ TICKET_AUTH_TAG_BYTES ) ) != 0 )
{
goto cleanup;
}
- if( ciph_len != clear_len )
+ if( ciph_len != clear_len + TICKET_AUTH_TAG_BYTES )
{
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto cleanup;
}
- *tlen = TICKET_MIN_LEN + ciph_len;
+ *tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES;
cleanup:
#if defined(MBEDTLS_THREADING_C)
@@ -423,14 +299,13 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_ticket_context *ctx = p_ticket;
mbedtls_ssl_ticket_key *key;
unsigned char *key_name = buf;
unsigned char *iv = buf + TICKET_KEY_NAME_BYTES;
unsigned char *enc_len_p = iv + TICKET_IV_BYTES;
unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES;
- unsigned char *tag;
size_t enc_len, clear_len;
if( ctx == NULL || ctx->f_rng == NULL )
@@ -448,7 +323,6 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
goto cleanup;
enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1];
- tag = ticket + enc_len;
if( len != TICKET_MIN_LEN + enc_len )
{
@@ -466,13 +340,13 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
}
/* Decrypt and authenticate */
- if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx,
+ if( ( ret = mbedtls_cipher_auth_decrypt_ext( &key->ctx,
iv, TICKET_IV_BYTES,
/* Additional data: key name, IV and length */
key_name, TICKET_ADD_DATA_LEN,
- ticket, enc_len,
- ticket, &clear_len,
- tag, TICKET_AUTH_TAG_BYTES ) ) != 0 )
+ ticket, enc_len + TICKET_AUTH_TAG_BYTES,
+ ticket, enc_len, &clear_len,
+ TICKET_AUTH_TAG_BYTES ) ) != 0 )
{
if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
ret = MBEDTLS_ERR_SSL_INVALID_MAC;
@@ -486,7 +360,7 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
}
/* Actually load session */
- if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 )
+ if( ( ret = mbedtls_ssl_session_load( session, ticket, clear_len ) ) != 0 )
goto cleanup;
#if defined(MBEDTLS_HAVE_TIME)
diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c
index 127276486b..2e6469de83 100644
--- a/thirdparty/mbedtls/library/ssl_tls.c
+++ b/thirdparty/mbedtls/library/ssl_tls.c
@@ -2,13 +2,7 @@
* SSLv3/TLSv1 shared functions
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The SSL 3.0 specification was drafted by Netscape in 1996,
@@ -52,11 +25,7 @@
* http://www.ietf.org/rfc/rfc4346.txt
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_TLS_C)
@@ -68,202 +37,120 @@
#define mbedtls_free free
#endif
-#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/version.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#include "psa/crypto.h"
+#endif
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/oid.h"
#endif
-static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
-static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
-
-/* Length of the "epoch" field in the record header */
-static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
-{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( 2 );
-#else
- ((void) ssl);
-#endif
- return( 0 );
-}
-
-/*
- * Start a timer.
- * Passing millisecs = 0 cancels a running timer.
- */
-static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
-{
- if( ssl->f_set_timer == NULL )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
- ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
-}
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+/* Top-level Connection ID API */
-/*
- * Return -1 is timer is expired, 0 if it isn't.
- */
-static int ssl_check_timer( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf,
+ size_t len,
+ int ignore_other_cid )
{
- if( ssl->f_get_timer == NULL )
- return( 0 );
+ if( len > MBEDTLS_SSL_CID_IN_LEN_MAX )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ssl->f_get_timer( ssl->p_timer ) == 2 )
+ if( ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_FAIL &&
+ ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE )
{
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
- return( -1 );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
+ conf->ignore_unexpected_cid = ignore_other_cid;
+ conf->cid_len = len;
return( 0 );
}
-static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
- mbedtls_ssl_transform *transform );
-static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
- mbedtls_ssl_transform *transform );
-
-#define SSL_DONT_FORCE_FLUSH 0
-#define SSL_FORCE_FLUSH 1
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-
-/* Forward declarations for functions related to message buffering. */
-static void ssl_buffering_free( mbedtls_ssl_context *ssl );
-static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
- uint8_t slot );
-static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
-static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
-static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
-static int ssl_buffer_message( mbedtls_ssl_context *ssl );
-static int ssl_buffer_future_record( mbedtls_ssl_context *ssl );
-static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
-
-static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl );
-static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
-{
- size_t mtu = ssl_get_current_mtu( ssl );
-
- if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN )
- return( mtu );
-
- return( MBEDTLS_SSL_OUT_BUFFER_LEN );
-}
-
-static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
+int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl,
+ int enable,
+ unsigned char const *own_cid,
+ size_t own_cid_len )
{
- size_t const bytes_written = ssl->out_left;
- size_t const mtu = ssl_get_maximum_datagram_size( ssl );
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- /* Double-check that the write-index hasn't gone
- * past what we can transmit in a single datagram. */
- if( bytes_written > mtu )
+ ssl->negotiate_cid = enable;
+ if( enable == MBEDTLS_SSL_CID_DISABLED )
{
- /* Should never happen... */
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- return( (int) ( mtu - bytes_written ) );
-}
-
-static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
-{
- int ret;
- size_t remaining, expansion;
- size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
-
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
-
- if( max_len > mfl )
- max_len = mfl;
-
- /* By the standard (RFC 6066 Sect. 4), the MFL extension
- * only limits the maximum record payload size, so in theory
- * we would be allowed to pack multiple records of payload size
- * MFL into a single datagram. However, this would mean that there's
- * no way to explicitly communicate MTU restrictions to the peer.
- *
- * The following reduction of max_len makes sure that we never
- * write datagrams larger than MFL + Record Expansion Overhead.
- */
- if( max_len <= ssl->out_left )
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Disable use of CID extension." ) );
return( 0 );
+ }
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Enable use of CID extension." ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Own CID", own_cid, own_cid_len );
- max_len -= ssl->out_left;
-#endif
-
- ret = ssl_get_remaining_space_in_datagram( ssl );
- if( ret < 0 )
- return( ret );
- remaining = (size_t) ret;
-
- ret = mbedtls_ssl_get_record_expansion( ssl );
- if( ret < 0 )
- return( ret );
- expansion = (size_t) ret;
-
- if( remaining <= expansion )
- return( 0 );
+ if( own_cid_len != ssl->conf->cid_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "CID length %u does not match CID length %u in config",
+ (unsigned) own_cid_len,
+ (unsigned) ssl->conf->cid_len ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
- remaining -= expansion;
- if( remaining >= max_len )
- remaining = max_len;
+ memcpy( ssl->own_cid, own_cid, own_cid_len );
+ /* Truncation is not an issue here because
+ * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */
+ ssl->own_cid_len = (uint8_t) own_cid_len;
- return( (int) remaining );
+ return( 0 );
}
-/*
- * Double the retransmit timeout value, within the allowed range,
- * returning -1 if the maximum value has already been reached.
- */
-static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl,
+ int *enabled,
+ unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ],
+ size_t *peer_cid_len )
{
- uint32_t new_timeout;
-
- if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
- return( -1 );
+ *enabled = MBEDTLS_SSL_CID_DISABLED;
- /* Implement the final paragraph of RFC 6347 section 4.1.1.1
- * in the following way: after the initial transmission and a first
- * retransmission, back off to a temporary estimated MTU of 508 bytes.
- * This value is guaranteed to be deliverable (if not guaranteed to be
- * delivered) of any compliant IPv4 (and IPv6) network, and should work
- * on most non-IP stacks too. */
- if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
- ssl->handshake->mtu = 508;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- new_timeout = 2 * ssl->handshake->retransmit_timeout;
+ /* We report MBEDTLS_SSL_CID_DISABLED in case the CID extensions
+ * were used, but client and server requested the empty CID.
+ * This is indistinguishable from not using the CID extension
+ * in the first place. */
+ if( ssl->transform_in->in_cid_len == 0 &&
+ ssl->transform_in->out_cid_len == 0 )
+ {
+ return( 0 );
+ }
- /* Avoid arithmetic overflow and range overflow */
- if( new_timeout < ssl->handshake->retransmit_timeout ||
- new_timeout > ssl->conf->hs_timeout_max )
+ if( peer_cid_len != NULL )
{
- new_timeout = ssl->conf->hs_timeout_max;
+ *peer_cid_len = ssl->transform_in->out_cid_len;
+ if( peer_cid != NULL )
+ {
+ memcpy( peer_cid, ssl->transform_in->out_cid,
+ ssl->transform_in->out_cid_len );
+ }
}
- ssl->handshake->retransmit_timeout = new_timeout;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
- ssl->handshake->retransmit_timeout ) );
+ *enabled = MBEDTLS_SSL_CID_ENABLED;
return( 0 );
}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
-{
- ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
- ssl->handshake->retransmit_timeout ) );
-}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
@@ -295,8 +182,8 @@ static unsigned int ssl_mfl_code_to_length( int mfl )
}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
-#if defined(MBEDTLS_SSL_CLI_C)
-static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src )
+int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
+ const mbedtls_ssl_session *src )
{
mbedtls_ssl_session_free( dst );
memcpy( dst, src, sizeof( mbedtls_ssl_session ) );
@@ -306,9 +193,11 @@ static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
+
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
if( src->peer_cert != NULL )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) );
if( dst->peer_cert == NULL )
@@ -324,6 +213,21 @@ static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session
return( ret );
}
}
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( src->peer_cert_digest != NULL )
+ {
+ dst->peer_cert_digest =
+ mbedtls_calloc( 1, src->peer_cert_digest_len );
+ if( dst->peer_cert_digest == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ memcpy( dst->peer_cert_digest, src->peer_cert_digest,
+ src->peer_cert_digest_len );
+ dst->peer_cert_digest_type = src->peer_cert_digest_type;
+ dst->peer_cert_digest_len = src->peer_cert_digest_len;
+ }
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
@@ -339,22 +243,95 @@ static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session
return( 0 );
}
-#endif /* MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
-int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
- const unsigned char *key_enc, const unsigned char *key_dec,
- size_t keylen,
- const unsigned char *iv_enc, const unsigned char *iv_dec,
- size_t ivlen,
- const unsigned char *mac_enc, const unsigned char *mac_dec,
- size_t maclen ) = NULL;
-int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
-int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
-int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
-int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
-int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+static int resize_buffer( unsigned char **buffer, size_t len_new, size_t *len_old )
+{
+ unsigned char* resized_buffer = mbedtls_calloc( 1, len_new );
+ if( resized_buffer == NULL )
+ return -1;
+
+ /* We want to copy len_new bytes when downsizing the buffer, and
+ * len_old bytes when upsizing, so we choose the smaller of two sizes,
+ * to fit one buffer into another. Size checks, ensuring that no data is
+ * lost, are done outside of this function. */
+ memcpy( resized_buffer, *buffer,
+ ( len_new < *len_old ) ? len_new : *len_old );
+ mbedtls_platform_zeroize( *buffer, *len_old );
+ mbedtls_free( *buffer );
+
+ *buffer = resized_buffer;
+ *len_old = len_new;
+
+ return 0;
+}
+
+static void handle_buffer_resizing( mbedtls_ssl_context *ssl, int downsizing,
+ size_t in_buf_new_len,
+ size_t out_buf_new_len )
+{
+ int modified = 0;
+ size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
+ size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
+ if( ssl->in_buf != NULL )
+ {
+ written_in = ssl->in_msg - ssl->in_buf;
+ iv_offset_in = ssl->in_iv - ssl->in_buf;
+ len_offset_in = ssl->in_len - ssl->in_buf;
+ if( downsizing ?
+ ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len :
+ ssl->in_buf_len < in_buf_new_len )
+ {
+ if( resize_buffer( &ssl->in_buf, in_buf_new_len, &ssl->in_buf_len ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %" MBEDTLS_PRINTF_SIZET,
+ in_buf_new_len ) );
+ modified = 1;
+ }
+ }
+ }
+
+ if( ssl->out_buf != NULL )
+ {
+ written_out = ssl->out_msg - ssl->out_buf;
+ iv_offset_out = ssl->out_iv - ssl->out_buf;
+ len_offset_out = ssl->out_len - ssl->out_buf;
+ if( downsizing ?
+ ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len :
+ ssl->out_buf_len < out_buf_new_len )
+ {
+ if( resize_buffer( &ssl->out_buf, out_buf_new_len, &ssl->out_buf_len ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %" MBEDTLS_PRINTF_SIZET,
+ out_buf_new_len ) );
+ modified = 1;
+ }
+ }
+ }
+ if( modified )
+ {
+ /* Update pointers here to avoid doing it twice. */
+ mbedtls_ssl_reset_in_out_pointers( ssl );
+ /* Fields below might not be properly updated with record
+ * splitting or with CID, so they are manually updated here. */
+ ssl->out_msg = ssl->out_buf + written_out;
+ ssl->out_len = ssl->out_buf + len_offset_out;
+ ssl->out_iv = ssl->out_buf + iv_offset_out;
+
+ ssl->in_msg = ssl->in_buf + written_in;
+ ssl->in_len = ssl->in_buf + len_offset_in;
+ ssl->in_iv = ssl->in_buf + iv_offset_in;
+ }
+}
+#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
/*
* Key material generation
@@ -429,16 +406,22 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
size_t nb, hs;
size_t i, j, k;
const unsigned char *S1, *S2;
- unsigned char tmp[128];
+ unsigned char *tmp;
+ size_t tmp_len = 0;
unsigned char h_i[20];
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_init( &md_ctx );
- if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ tmp_len = 20 + strlen( label ) + rlen;
+ tmp = mbedtls_calloc( 1, tmp_len );
+ if( tmp == NULL )
+ {
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ goto exit;
+ }
hs = ( slen + 1 ) / 2;
S1 = secret;
@@ -459,7 +442,9 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
}
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+ {
goto exit;
+ }
ret = mbedtls_md_hmac_starts( &md_ctx, S1, hs );
if( ret != 0 )
@@ -511,7 +496,9 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
}
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+ {
goto exit;
+ }
ret = mbedtls_md_hmac_starts( &md_ctx, S2, hs );
if( ret != 0 )
@@ -554,14 +541,144 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
exit:
mbedtls_md_free( &md_ctx );
- mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+ mbedtls_platform_zeroize( tmp, tmp_len );
mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
- return( 0 );
+ mbedtls_free( tmp );
+ return( ret );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* derivation,
+ psa_key_id_t key,
+ psa_algorithm_t alg,
+ const unsigned char* seed, size_t seed_length,
+ const unsigned char* label, size_t label_length,
+ size_t capacity )
+{
+ psa_status_t status;
+
+ status = psa_key_derivation_setup( derivation, alg );
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ if( PSA_ALG_IS_TLS12_PRF( alg ) || PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
+ {
+ status = psa_key_derivation_input_bytes( derivation,
+ PSA_KEY_DERIVATION_INPUT_SEED,
+ seed, seed_length );
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ if( mbedtls_svc_key_id_is_null( key ) )
+ {
+ status = psa_key_derivation_input_bytes(
+ derivation, PSA_KEY_DERIVATION_INPUT_SECRET,
+ NULL, 0 );
+ }
+ else
+ {
+ status = psa_key_derivation_input_key(
+ derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key );
+ }
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ status = psa_key_derivation_input_bytes( derivation,
+ PSA_KEY_DERIVATION_INPUT_LABEL,
+ label, label_length );
+ if( status != PSA_SUCCESS )
+ return( status );
+ }
+ else
+ {
+ return( PSA_ERROR_NOT_SUPPORTED );
+ }
+
+ status = psa_key_derivation_set_capacity( derivation, capacity );
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ return( PSA_SUCCESS );
+}
+
+static int tls_prf_generic( mbedtls_md_type_t md_type,
+ const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen )
+{
+ psa_status_t status;
+ psa_algorithm_t alg;
+ psa_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_derivation_operation_t derivation =
+ PSA_KEY_DERIVATION_OPERATION_INIT;
+
+ if( md_type == MBEDTLS_MD_SHA384 )
+ alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
+ else
+ alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
+
+ /* Normally a "secret" should be long enough to be impossible to
+ * find by brute force, and in particular should not be empty. But
+ * this PRF is also used to derive an IV, in particular in EAP-TLS,
+ * and for this use case it makes sense to have a 0-length "secret".
+ * Since the key API doesn't allow importing a key of length 0,
+ * keep master_key=0, which setup_psa_key_derivation() understands
+ * to mean a 0-length "secret" input. */
+ if( slen != 0 )
+ {
+ psa_key_attributes_t key_attributes = psa_key_attributes_init();
+ psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
+ psa_set_key_algorithm( &key_attributes, alg );
+ psa_set_key_type( &key_attributes, PSA_KEY_TYPE_DERIVE );
+
+ status = psa_import_key( &key_attributes, secret, slen, &master_key );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = setup_psa_key_derivation( &derivation,
+ master_key, alg,
+ random, rlen,
+ (unsigned char const *) label,
+ (size_t) strlen( label ),
+ dlen );
+ if( status != PSA_SUCCESS )
+ {
+ psa_key_derivation_abort( &derivation );
+ psa_destroy_key( master_key );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_key_derivation_output_bytes( &derivation, dstbuf, dlen );
+ if( status != PSA_SUCCESS )
+ {
+ psa_key_derivation_abort( &derivation );
+ psa_destroy_key( master_key );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_key_derivation_abort( &derivation );
+ if( status != PSA_SUCCESS )
+ {
+ psa_destroy_key( master_key );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ if( ! mbedtls_svc_key_id_is_null( master_key ) )
+ status = psa_destroy_key( master_key );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ return( 0 );
+}
+
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+
static int tls_prf_generic( mbedtls_md_type_t md_type,
const unsigned char *secret, size_t slen,
const char *label,
@@ -570,11 +687,12 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
{
size_t nb;
size_t i, j, k, md_len;
- unsigned char tmp[128];
+ unsigned char *tmp;
+ size_t tmp_len = 0;
unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_init( &md_ctx );
@@ -583,8 +701,13 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
md_len = mbedtls_md_get_size( md_info );
- if( sizeof( tmp ) < md_len + strlen( label ) + rlen )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ tmp_len = md_len + strlen( label ) + rlen;
+ tmp = mbedtls_calloc( 1, tmp_len );
+ if( tmp == NULL )
+ {
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ goto exit;
+ }
nb = strlen( label );
memcpy( tmp + md_len, label, nb );
@@ -638,12 +761,14 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
exit:
mbedtls_md_free( &md_ctx );
- mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+ mbedtls_platform_zeroize( tmp, tmp_len );
mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
- return( 0 );
-}
+ mbedtls_free( tmp );
+ return( ret );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SHA256_C)
static int tls_prf_sha256( const unsigned char *secret, size_t slen,
const char *label,
@@ -655,7 +780,7 @@ static int tls_prf_sha256( const unsigned char *secret, size_t slen,
}
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static int tls_prf_sha384( const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
@@ -664,7 +789,7 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen,
return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen,
label, random, rlen, dstbuf, dlen ) );
}
-#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t );
@@ -675,207 +800,265 @@ static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned c
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3)
-static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_verify_ssl( const mbedtls_ssl_context *, unsigned char *, size_t * );
static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int );
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_verify_tls( const mbedtls_ssl_context *, unsigned char*, size_t * );
static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int );
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char*, size_t * );
static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char*, size_t * );
static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
{
- int ret = 0;
- unsigned char tmp[64];
- unsigned char keyblk[256];
- unsigned char *key1;
- unsigned char *key2;
- unsigned char *mac_enc;
- unsigned char *mac_dec;
- size_t mac_key_len;
- size_t iv_copy_len;
- const mbedtls_cipher_info_t *cipher_info;
- const mbedtls_md_info_t *md_info;
-
- mbedtls_ssl_session *session = ssl->session_negotiate;
- mbedtls_ssl_transform *transform = ssl->transform_negotiate;
- mbedtls_ssl_handshake_params *handshake = ssl->handshake;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
-
- cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher );
- if( cipher_info == NULL )
+ if( ssl->conf->f_psk != NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
- transform->ciphersuite_info->cipher ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
+ /* If we've used a callback to select the PSK,
+ * the static configuration is irrelevant. */
+ if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+ return( 1 );
- md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac );
- if( md_info == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found",
- transform->ciphersuite_info->mac ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ return( 0 );
}
- /*
- * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
- */
+ if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
+ return( 1 );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+static mbedtls_tls_prf_types tls_prf_get_type( mbedtls_ssl_tls_prf_cb *tls_prf )
+{
#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ if( tls_prf == ssl3_prf )
{
- handshake->tls_prf = ssl3_prf;
- handshake->calc_verify = ssl_calc_verify_ssl;
- handshake->calc_finished = ssl_calc_finished_ssl;
+ return( MBEDTLS_SSL_TLS_PRF_SSL3 );
}
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+ if( tls_prf == tls1_prf )
{
- handshake->tls_prf = tls1_prf;
- handshake->calc_verify = ssl_calc_verify_tls;
- handshake->calc_finished = ssl_calc_finished_tls;
+ return( MBEDTLS_SSL_TLS_PRF_TLS1 );
}
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA512_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
- transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ if( tls_prf == tls_prf_sha384 )
{
- handshake->tls_prf = tls_prf_sha384;
- handshake->calc_verify = ssl_calc_verify_tls_sha384;
- handshake->calc_finished = ssl_calc_finished_tls_sha384;
+ return( MBEDTLS_SSL_TLS_PRF_SHA384 );
}
else
#endif
#if defined(MBEDTLS_SHA256_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ if( tls_prf == tls_prf_sha256 )
{
- handshake->tls_prf = tls_prf_sha256;
- handshake->calc_verify = ssl_calc_verify_tls_sha256;
- handshake->calc_finished = ssl_calc_finished_tls_sha256;
+ return( MBEDTLS_SSL_TLS_PRF_SHA256 );
}
else
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
+ return( MBEDTLS_SSL_TLS_PRF_NONE );
+}
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
- /*
- * SSLv3:
- * master =
- * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) +
- * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) +
- * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
- *
- * TLSv1+:
- * master = PRF( premaster, "master secret", randbytes )[0..47]
- */
- if( handshake->resume == 0 )
+int mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf,
+ const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen )
+{
+ mbedtls_ssl_tls_prf_cb *tls_prf = NULL;
+
+ switch( prf )
{
- MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
- handshake->pmslen );
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ case MBEDTLS_SSL_TLS_PRF_SSL3:
+ tls_prf = ssl3_prf;
+ break;
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+ case MBEDTLS_SSL_TLS_PRF_TLS1:
+ tls_prf = tls1_prf;
+ break;
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
- {
- unsigned char session_hash[48];
- size_t hash_len;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_SSL_TLS_PRF_SHA384:
+ tls_prf = tls_prf_sha384;
+ break;
+#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_SSL_TLS_PRF_SHA256:
+ tls_prf = tls_prf_sha256;
+ break;
+#endif /* MBEDTLS_SHA256_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+ default:
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) );
+ return( tls_prf( secret, slen, label, random, rlen, dstbuf, dlen ) );
+}
- ssl->handshake->calc_verify( ssl, session_hash );
+/* Type for the TLS PRF */
+typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
+ const unsigned char *, size_t,
+ unsigned char *, size_t);
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
-#if defined(MBEDTLS_SHA512_C)
- if( ssl->transform_negotiate->ciphersuite_info->mac ==
- MBEDTLS_MD_SHA384 )
- {
- hash_len = 48;
- }
- else
+/*
+ * Populate a transform structure with session keys and all the other
+ * necessary information.
+ *
+ * Parameters:
+ * - [in/out]: transform: structure to populate
+ * [in] must be just initialised with mbedtls_ssl_transform_init()
+ * [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf()
+ * - [in] ciphersuite
+ * - [in] master
+ * - [in] encrypt_then_mac
+ * - [in] trunc_hmac
+ * - [in] compression
+ * - [in] tls_prf: pointer to PRF to use for key derivation
+ * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
+ * - [in] minor_ver: SSL/TLS minor version
+ * - [in] endpoint: client or server
+ * - [in] ssl: optionally used for:
+ * - MBEDTLS_SSL_HW_RECORD_ACCEL: whole context (non-const)
+ * - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
+ * - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
+ */
+static int ssl_populate_transform( mbedtls_ssl_transform *transform,
+ int ciphersuite,
+ const unsigned char master[48],
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ int encrypt_then_mac,
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ int trunc_hmac,
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ int compression,
#endif
- hash_len = 32;
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- hash_len = 36;
-
- MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len );
+ ssl_tls_prf_t tls_prf,
+ const unsigned char randbytes[64],
+ int minor_ver,
+ unsigned endpoint,
+#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ const
+#endif
+ mbedtls_ssl_context *ssl )
+{
+ int ret = 0;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ int psa_fallthrough;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ unsigned char keyblk[256];
+ unsigned char *key1;
+ unsigned char *key2;
+ unsigned char *mac_enc;
+ unsigned char *mac_dec;
+ size_t mac_key_len = 0;
+ size_t iv_copy_len;
+ unsigned keylen;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+ const mbedtls_cipher_info_t *cipher_info;
+ const mbedtls_md_info_t *md_info;
- ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
- "extended master secret",
- session_hash, hash_len,
- session->master, 48 );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
- return( ret );
- }
+#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) && \
+ !defined(MBEDTLS_SSL_EXPORT_KEYS) && \
+ !defined(MBEDTLS_DEBUG_C)
+ ssl = NULL; /* make sure we don't use it except for those cases */
+ (void) ssl;
+#endif
- }
- else
+ /*
+ * Some data just needs copying into the structure
+ */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
+ defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ transform->encrypt_then_mac = encrypt_then_mac;
#endif
- ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
- "master secret",
- handshake->randbytes, 64,
- session->master, 48 );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
- return( ret );
- }
+ transform->minor_ver = minor_ver;
- mbedtls_platform_zeroize( handshake->premaster,
- sizeof(handshake->premaster) );
- }
- else
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+ memcpy( transform->randbytes, randbytes, sizeof( transform->randbytes ) );
+#endif
/*
- * Swap the client and server random values.
+ * Get various info structures
*/
- memcpy( tmp, handshake->randbytes, 64 );
- memcpy( handshake->randbytes, tmp + 32, 32 );
- memcpy( handshake->randbytes + 32, tmp, 32 );
- mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+ ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
+ if( ciphersuite_info == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %d not found",
+ ciphersuite ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
+ if( cipher_info == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %u not found",
+ ciphersuite_info->cipher ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ md_info = mbedtls_md_info_from_type( ciphersuite_info->mac );
+ if( md_info == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %u not found",
+ (unsigned) ciphersuite_info->mac ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* Copy own and peer's CID if the use of the CID
+ * extension has been negotiated. */
+ if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Copy CIDs into SSL transform" ) );
+
+ transform->in_cid_len = ssl->own_cid_len;
+ memcpy( transform->in_cid, ssl->own_cid, ssl->own_cid_len );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Incoming CID", transform->in_cid,
+ transform->in_cid_len );
+
+ transform->out_cid_len = ssl->handshake->peer_cid_len;
+ memcpy( transform->out_cid, ssl->handshake->peer_cid,
+ ssl->handshake->peer_cid_len );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Outgoing CID", transform->out_cid,
+ transform->out_cid_len );
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
/*
- * SSLv3:
- * key block =
- * MD5( master + SHA1( 'A' + master + randbytes ) ) +
- * MD5( master + SHA1( 'BB' + master + randbytes ) ) +
- * MD5( master + SHA1( 'CCC' + master + randbytes ) ) +
- * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
- * ...
- *
- * TLSv1:
- * key block = PRF( master, "key expansion", randbytes )
+ * Compute key block using the PRF
*/
- ret = handshake->tls_prf( session->master, 48, "key expansion",
- handshake->randbytes, 64, keyblk, 256 );
+ ret = tls_prf( master, 48, "key expansion", randbytes, 64, keyblk, 256 );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
@@ -883,56 +1066,70 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
- mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 );
- MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
+ mbedtls_ssl_get_ciphersuite_name( ciphersuite ) ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", master, 48 );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", randbytes, 64 );
MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
- mbedtls_platform_zeroize( handshake->randbytes,
- sizeof( handshake->randbytes ) );
-
/*
* Determine the appropriate key, IV and MAC length.
*/
- transform->keylen = cipher_info->key_bitlen / 8;
+ keylen = cipher_info->key_bitlen / 8;
+#if defined(MBEDTLS_GCM_C) || \
+ defined(MBEDTLS_CCM_C) || \
+ defined(MBEDTLS_CHACHAPOLY_C)
if( cipher_info->mode == MBEDTLS_MODE_GCM ||
cipher_info->mode == MBEDTLS_MODE_CCM ||
cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
{
- size_t taglen, explicit_ivlen;
+ size_t explicit_ivlen;
transform->maclen = 0;
mac_key_len = 0;
-
- /* All modes haves 96-bit IVs;
- * GCM and CCM has 4 implicit and 8 explicit bytes
- * ChachaPoly has all 12 bytes implicit
+ transform->taglen =
+ ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
+
+ /* All modes haves 96-bit IVs, but the length of the static parts vary
+ * with mode and version:
+ * - For GCM and CCM in TLS 1.2, there's a static IV of 4 Bytes
+ * (to be concatenated with a dynamically chosen IV of 8 Bytes)
+ * - For ChaChaPoly in TLS 1.2, and all modes in TLS 1.3, there's
+ * a static IV of 12 Bytes (to be XOR'ed with the 8 Byte record
+ * sequence number).
*/
transform->ivlen = 12;
- if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+ {
transform->fixed_ivlen = 12;
+ }
else
- transform->fixed_ivlen = 4;
-
- /* All modes have 128-bit tags, except CCM_8 (ciphersuite flag) */
- taglen = transform->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
-
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+ {
+ if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+ transform->fixed_ivlen = 12;
+ else
+ transform->fixed_ivlen = 4;
+ }
/* Minimum length of encrypted record */
explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
- transform->minlen = explicit_ivlen + taglen;
+ transform->minlen = explicit_ivlen + transform->taglen;
}
else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ if( cipher_info->mode == MBEDTLS_MODE_STREAM ||
+ cipher_info->mode == MBEDTLS_MODE_CBC )
{
/* Initialize HMAC contexts */
if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
- return( ret );
+ goto end;
}
/* Get MAC length */
@@ -945,7 +1142,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
* (rfc 6066 page 13 or rfc 2104 section 4),
* so we only need to adjust the length here.
*/
- if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
+ if( trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
{
transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
@@ -973,7 +1170,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
* 2. IV except for SSL3 and TLS 1.0
*/
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
+ if( encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
{
transform->minlen = transform->maclen
+ cipher_info->block_size;
@@ -987,14 +1184,14 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 )
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
+ minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 )
; /* No need to adjust minlen */
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
+ minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
transform->minlen += transform->ivlen;
}
@@ -1002,23 +1199,32 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#endif
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ goto end;
}
}
}
+ else
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
- transform->keylen, transform->minlen, transform->ivlen,
- transform->maclen ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %u, minlen: %u, ivlen: %u, maclen: %u",
+ (unsigned) keylen,
+ (unsigned) transform->minlen,
+ (unsigned) transform->ivlen,
+ (unsigned) transform->maclen ) );
/*
* Finally setup the cipher contexts, IVs and MAC secrets.
*/
#if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+ if( endpoint == MBEDTLS_SSL_IS_CLIENT )
{
key1 = keyblk + mac_key_len * 2;
- key2 = keyblk + mac_key_len * 2 + transform->keylen;
+ key2 = keyblk + mac_key_len * 2 + keylen;
mac_enc = keyblk;
mac_dec = keyblk + mac_key_len;
@@ -1028,16 +1234,16 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
*/
iv_copy_len = ( transform->fixed_ivlen ) ?
transform->fixed_ivlen : transform->ivlen;
- memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len );
- memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len,
+ memcpy( transform->iv_enc, key2 + keylen, iv_copy_len );
+ memcpy( transform->iv_dec, key2 + keylen + iv_copy_len,
iv_copy_len );
}
else
#endif /* MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+ if( endpoint == MBEDTLS_SSL_IS_SERVER )
{
- key1 = keyblk + mac_key_len * 2 + transform->keylen;
+ key1 = keyblk + mac_key_len * 2 + keylen;
key2 = keyblk + mac_key_len * 2;
mac_enc = keyblk + mac_key_len;
@@ -1048,24 +1254,27 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
*/
iv_copy_len = ( transform->fixed_ivlen ) ?
transform->fixed_ivlen : transform->ivlen;
- memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len );
- memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len,
+ memcpy( transform->iv_dec, key1 + keylen, iv_copy_len );
+ memcpy( transform->iv_enc, key1 + keylen + iv_copy_len,
iv_copy_len );
}
else
#endif /* MBEDTLS_SSL_SRV_C */
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ goto end;
}
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{
- if( mac_key_len > sizeof transform->mac_enc )
+ if( mac_key_len > sizeof( transform->mac_enc ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ goto end;
}
memcpy( transform->mac_enc, mac_enc, mac_key_len );
@@ -1075,7 +1284,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+ if( minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
{
/* For HMAC-based ciphersuites, initialize the HMAC transforms.
For AEAD-based ciphersuites, there is nothing to do here. */
@@ -1084,59 +1293,151 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
ret = mbedtls_md_hmac_starts( &transform->md_ctx_enc,
mac_enc, mac_key_len );
if( ret != 0 )
- return( ret );
+ goto end;
ret = mbedtls_md_hmac_starts( &transform->md_ctx_dec,
mac_dec, mac_key_len );
if( ret != 0 )
- return( ret );
+ goto end;
}
}
else
#endif
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ goto end;
}
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_init != NULL )
{
+ ret = 0;
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
- if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen,
+ if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, keylen,
transform->iv_enc, transform->iv_dec,
iv_copy_len,
mac_enc, mac_dec,
mac_key_len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
+ goto end;
}
}
+#else
+ ((void) mac_dec);
+ ((void) mac_enc);
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( ssl->conf->f_export_keys != NULL )
{
ssl->conf->f_export_keys( ssl->conf->p_export_keys,
- session->master, keyblk,
- mac_key_len, transform->keylen,
+ master, keyblk,
+ mac_key_len, keylen,
iv_copy_len );
}
+
+ if( ssl->conf->f_export_keys_ext != NULL )
+ {
+ ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys,
+ master, keyblk,
+ mac_key_len, keylen,
+ iv_copy_len,
+ randbytes + 32,
+ randbytes,
+ tls_prf_get_type( tls_prf ) );
+ }
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+ /* Only use PSA-based ciphers for TLS-1.2.
+ * That's relevant at least for TLS-1.0, where
+ * we assume that mbedtls_cipher_crypt() updates
+ * the structure field for the IV, which the PSA-based
+ * implementation currently doesn't. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_enc,
+ cipher_info, transform->taglen );
+ if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
+ goto end;
+ }
+
+ if( ret == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based encryption cipher context" ) );
+ psa_fallthrough = 0;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record encryption - fall through to default setup." ) );
+ psa_fallthrough = 1;
+ }
+ }
+ else
+ psa_fallthrough = 1;
+#else
+ psa_fallthrough = 1;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ if( psa_fallthrough == 1 )
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
cipher_info ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
- return( ret );
+ goto end;
+ }
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Only use PSA-based ciphers for TLS-1.2.
+ * That's relevant at least for TLS-1.0, where
+ * we assume that mbedtls_cipher_crypt() updates
+ * the structure field for the IV, which the PSA-based
+ * implementation currently doesn't. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_dec,
+ cipher_info, transform->taglen );
+ if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
+ goto end;
+ }
+
+ if( ret == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based decryption cipher context" ) );
+ psa_fallthrough = 0;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record decryption - fall through to default setup." ) );
+ psa_fallthrough = 1;
+ }
}
+ else
+ psa_fallthrough = 1;
+#else
+ psa_fallthrough = 1;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+ if( psa_fallthrough == 1 )
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
cipher_info ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
- return( ret );
+ goto end;
}
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
@@ -1144,7 +1445,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_ENCRYPT ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
- return( ret );
+ goto end;
}
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
@@ -1152,7 +1453,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_DECRYPT ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
- return( ret );
+ goto end;
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1162,37 +1463,23 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_PADDING_NONE ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
- return( ret );
+ goto end;
}
if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
MBEDTLS_PADDING_NONE ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
- return( ret );
+ goto end;
}
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
- mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
+ /* Initialize Zlib contexts */
#if defined(MBEDTLS_ZLIB_SUPPORT)
- // Initialize compression
- //
- if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+ if( compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
{
- if( ssl->compress_buf == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
- ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
- if( ssl->compress_buf == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
- MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- }
-
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) );
memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) );
@@ -1203,18 +1490,317 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
inflateInit( &transform->ctx_inflate ) != Z_OK )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+ ret = MBEDTLS_ERR_SSL_COMPRESSION_FAILED;
+ goto end;
}
}
#endif /* MBEDTLS_ZLIB_SUPPORT */
+end:
+ mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
+ return( ret );
+}
+
+/*
+ * Set appropriate PRF function and other SSL / TLS 1.0/1.1 / TLS1.2 functions
+ *
+ * Inputs:
+ * - SSL/TLS minor version
+ * - hash associated with the ciphersuite (only used by TLS 1.2)
+ *
+ * Outputs:
+ * - the tls_prf, calc_verify and calc_finished members of handshake structure
+ */
+static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake,
+ int minor_ver,
+ mbedtls_md_type_t hash )
+{
+#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || \
+ !( defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384) )
+ (void) hash;
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ handshake->tls_prf = ssl3_prf;
+ handshake->calc_verify = ssl_calc_verify_ssl;
+ handshake->calc_finished = ssl_calc_finished_ssl;
+ }
+ else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+ if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ handshake->tls_prf = tls1_prf;
+ handshake->calc_verify = ssl_calc_verify_tls;
+ handshake->calc_finished = ssl_calc_finished_tls;
+ }
+ else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+ hash == MBEDTLS_MD_SHA384 )
+ {
+ handshake->tls_prf = tls_prf_sha384;
+ handshake->calc_verify = ssl_calc_verify_tls_sha384;
+ handshake->calc_finished = ssl_calc_finished_tls_sha384;
+ }
+ else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ handshake->tls_prf = tls_prf_sha256;
+ handshake->calc_verify = ssl_calc_verify_tls_sha256;
+ handshake->calc_finished = ssl_calc_finished_tls_sha256;
+ }
+ else
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+ {
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Compute master secret if needed
+ *
+ * Parameters:
+ * [in/out] handshake
+ * [in] resume, premaster, extended_ms, calc_verify, tls_prf
+ * (PSA-PSK) ciphersuite_info, psk_opaque
+ * [out] premaster (cleared)
+ * [out] master
+ * [in] ssl: optionally used for debugging, EMS and PSA-PSK
+ * debug: conf->f_dbg, conf->p_dbg
+ * EMS: passed to calc_verify (debug + (SSL3) session_negotiate)
+ * PSA-PSA: minor_ver, conf
+ */
+static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
+ unsigned char *master,
+ const mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* cf. RFC 5246, Section 8.1:
+ * "The master secret is always exactly 48 bytes in length." */
+ size_t const master_secret_len = 48;
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+ unsigned char session_hash[48];
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+ /* The label for the KDF used for key expansion.
+ * This is either "master secret" or "extended master secret"
+ * depending on whether the Extended Master Secret extension
+ * is used. */
+ char const *lbl = "master secret";
+
+ /* The salt for the KDF used for key expansion.
+ * - If the Extended Master Secret extension is not used,
+ * this is ClientHello.Random + ServerHello.Random
+ * (see Sect. 8.1 in RFC 5246).
+ * - If the Extended Master Secret extension is used,
+ * this is the transcript of the handshake so far.
+ * (see Sect. 4 in RFC 7627). */
+ unsigned char const *salt = handshake->randbytes;
+ size_t salt_len = 64;
+
+#if !defined(MBEDTLS_DEBUG_C) && \
+ !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
+ !(defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED))
+ ssl = NULL; /* make sure we don't use it except for those cases */
+ (void) ssl;
+#endif
+
+ if( handshake->resume != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
+ return( 0 );
+ }
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+ if( handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
+ {
+ lbl = "extended master secret";
+ salt = session_hash;
+ handshake->calc_verify( ssl, session_hash, &salt_len );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret",
+ session_hash, salt_len );
+ }
+#endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+ if( handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
+ ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+ ssl_use_opaque_psk( ssl ) == 1 )
+ {
+ /* Perform PSK-to-MS expansion in a single step. */
+ psa_status_t status;
+ psa_algorithm_t alg;
+ psa_key_id_t psk;
+ psa_key_derivation_operation_t derivation =
+ PSA_KEY_DERIVATION_OPERATION_INIT;
+ mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PSK-to-MS expansion" ) );
+
+ psk = mbedtls_ssl_get_opaque_psk( ssl );
+
+ if( hash_alg == MBEDTLS_MD_SHA384 )
+ alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
+ else
+ alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
+
+ status = setup_psa_key_derivation( &derivation, psk, alg,
+ salt, salt_len,
+ (unsigned char const *) lbl,
+ (size_t) strlen( lbl ),
+ master_secret_len );
+ if( status != PSA_SUCCESS )
+ {
+ psa_key_derivation_abort( &derivation );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_key_derivation_output_bytes( &derivation,
+ master,
+ master_secret_len );
+ if( status != PSA_SUCCESS )
+ {
+ psa_key_derivation_abort( &derivation );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_key_derivation_abort( &derivation );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+ else
+#endif
+ {
+ ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
+ lbl, salt, salt_len,
+ master,
+ master_secret_len );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
+ return( ret );
+ }
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret",
+ handshake->premaster,
+ handshake->pmslen );
+
+ mbedtls_platform_zeroize( handshake->premaster,
+ sizeof(handshake->premaster) );
+ }
+
+ return( 0 );
+}
+
+int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
+
+ /* Set PRF, calc_verify and calc_finished function pointers */
+ ret = ssl_set_handshake_prfs( ssl->handshake,
+ ssl->minor_ver,
+ ciphersuite_info->mac );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_set_handshake_prfs", ret );
+ return( ret );
+ }
+
+ /* Compute master secret if needed */
+ ret = ssl_compute_master( ssl->handshake,
+ ssl->session_negotiate->master,
+ ssl );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compute_master", ret );
+ return( ret );
+ }
+
+ /* Swap the client and server random values:
+ * - MS derivation wanted client+server (RFC 5246 8.1)
+ * - key derivation wants server+client (RFC 5246 6.3) */
+ {
+ unsigned char tmp[64];
+ memcpy( tmp, ssl->handshake->randbytes, 64 );
+ memcpy( ssl->handshake->randbytes, tmp + 32, 32 );
+ memcpy( ssl->handshake->randbytes + 32, tmp, 32 );
+ mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+ }
+
+ /* Populate transform structure */
+ ret = ssl_populate_transform( ssl->transform_negotiate,
+ ssl->session_negotiate->ciphersuite,
+ ssl->session_negotiate->master,
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ ssl->session_negotiate->encrypt_then_mac,
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ ssl->session_negotiate->trunc_hmac,
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ ssl->session_negotiate->compression,
+#endif
+ ssl->handshake->tls_prf,
+ ssl->handshake->randbytes,
+ ssl->minor_ver,
+ ssl->conf->endpoint,
+ ssl );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_populate_transform", ret );
+ return( ret );
+ }
+
+ /* We no longer need Server/ClientHello.random values */
+ mbedtls_platform_zeroize( ssl->handshake->randbytes,
+ sizeof( ssl->handshake->randbytes ) );
+
+ /* Allocate compression buffer */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ if( ssl->session_negotiate->compression == MBEDTLS_SSL_COMPRESS_DEFLATE &&
+ ssl->compress_buf == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
+ ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
+ if( ssl->compress_buf == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+ MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
+ }
+#endif
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
return( 0 );
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
-void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash )
+void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl,
+ unsigned char *hash,
+ size_t *hlen )
{
mbedtls_md5_context md5;
mbedtls_sha1_context sha1;
@@ -1252,7 +1838,9 @@ void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash )
mbedtls_sha1_update_ret( &sha1, hash + 16, 20 );
mbedtls_sha1_finish_ret( &sha1, hash + 16 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
+ *hlen = 36;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_md5_free( &md5 );
@@ -1263,7 +1851,9 @@ void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash )
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash )
+void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl,
+ unsigned char *hash,
+ size_t *hlen )
{
mbedtls_md5_context md5;
mbedtls_sha1_context sha1;
@@ -1276,10 +1866,12 @@ void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash )
mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
- mbedtls_md5_finish_ret( &md5, hash );
+ mbedtls_md5_finish_ret( &md5, hash );
mbedtls_sha1_finish_ret( &sha1, hash + 16 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
+ *hlen = 36;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_md5_free( &md5 );
@@ -1291,8 +1883,34 @@ void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash )
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
-void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *hash )
+void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl,
+ unsigned char *hash,
+ size_t *hlen )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_status_t status;
+ psa_hash_operation_t sha256_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha256" ) );
+ status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha256_psa, hash, 32, &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+
+ *hlen = 32;
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, *hlen );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
+#else
mbedtls_sha256_context sha256;
mbedtls_sha256_init( &sha256 );
@@ -1302,18 +1920,46 @@ void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *hash )
mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
mbedtls_sha256_finish_ret( &sha256, hash );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
+ *hlen = 32;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_sha256_free( &sha256 );
-
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return;
}
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
-void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *hash )
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl,
+ unsigned char *hash,
+ size_t *hlen )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_status_t status;
+ psa_hash_operation_t sha384_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha384" ) );
+ status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha384_psa, hash, 48, &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+
+ *hlen = 48;
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, *hlen );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
+#else
mbedtls_sha512_context sha512;
mbedtls_sha512_init( &sha512 );
@@ -1323,29 +1969,35 @@ void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *hash )
mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
mbedtls_sha512_finish_ret( &sha512, hash );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
+ *hlen = 48;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_sha512_free( &sha512 );
-
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return;
}
-#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
{
unsigned char *p = ssl->handshake->premaster;
unsigned char *end = p + sizeof( ssl->handshake->premaster );
- const unsigned char *psk = ssl->conf->psk;
- size_t psk_len = ssl->conf->psk_len;
+ const unsigned char *psk = NULL;
+ size_t psk_len = 0;
- /* If the psk callback was called, use its result */
- if( ssl->handshake->psk != NULL )
+ if( mbedtls_ssl_get_psk( ssl, &psk, &psk_len )
+ == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED )
{
- psk = ssl->handshake->psk;
- psk_len = ssl->handshake->psk_len;
+ /*
+ * This should never happen because the existence of a PSK is always
+ * checked before calling this function
+ */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
/*
@@ -1361,8 +2013,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
if( end - p < 2 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- *(p++) = (unsigned char)( psk_len >> 8 );
- *(p++) = (unsigned char)( psk_len );
+ MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
+ p += 2;
if( end < p || (size_t)( end - p ) < psk_len )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -1391,7 +2043,7 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/* Write length only when we know the actual value */
@@ -1402,9 +2054,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
return( ret );
}
- *(p++) = (unsigned char)( len >> 8 );
- *(p++) = (unsigned char)( len );
- p += len;
+ MBEDTLS_PUT_UINT16_BE( len, p, 0 );
+ p += 2 + len;
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
}
@@ -1413,7 +2064,7 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t zlen;
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
@@ -1424,9 +2075,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
return( ret );
}
- *(p++) = (unsigned char)( zlen >> 8 );
- *(p++) = (unsigned char)( zlen );
- p += zlen;
+ MBEDTLS_PUT_UINT16_BE( zlen, p, 0 );
+ p += 2 + zlen;
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Z );
@@ -1442,8 +2092,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
if( end - p < 2 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- *(p++) = (unsigned char)( psk_len >> 8 );
- *(p++) = (unsigned char)( psk_len );
+ MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
+ p += 2;
if( end < p || (size_t)( end - p ) < psk_len )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -1455,1302 +2105,13 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
return( 0 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
-/*
- * SSLv3.0 MAC functions
- */
-#define SSL_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */
-static int ssl_mac( mbedtls_md_context_t *md_ctx,
- const unsigned char *secret,
- const unsigned char *buf, size_t len,
- const unsigned char *ctr, int type,
- unsigned char out[SSL_MAC_MAX_BYTES] )
-{
- unsigned char header[11];
- unsigned char padding[48];
- int padlen;
- int md_size = mbedtls_md_get_size( md_ctx->md_info );
- int md_type = mbedtls_md_get_type( md_ctx->md_info );
- int ret;
-
- /* Only MD5 and SHA-1 supported */
- if( md_type == MBEDTLS_MD_MD5 )
- padlen = 48;
- else
- padlen = 40;
-
- memcpy( header, ctr, 8 );
- header[ 8] = (unsigned char) type;
- header[ 9] = (unsigned char)( len >> 8 );
- header[10] = (unsigned char)( len );
-
- memset( padding, 0x36, padlen );
- ret = mbedtls_md_starts( md_ctx );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, secret, md_size );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, padding, padlen );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, header, 11 );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, buf, len );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_finish( md_ctx, out );
- if( ret != 0 )
- return( ret );
-
- memset( padding, 0x5C, padlen );
- ret = mbedtls_md_starts( md_ctx );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, secret, md_size );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, padding, padlen );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, out, md_size );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_finish( md_ctx, out );
- if( ret != 0 )
- return( ret );
-
- return( 0 );
-}
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
- defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
-#define SSL_SOME_MODES_USE_MAC
-#endif
-
-/*
- * Encryption/decryption functions
- */
-static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
-{
- mbedtls_cipher_mode_t mode;
- int auth_done = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
-
- if( ssl->session_out == NULL || ssl->transform_out == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
-
- /*
- * Add MAC before if needed
- */
-#if defined(SSL_SOME_MODES_USE_MAC)
- if( mode == MBEDTLS_MODE_STREAM ||
- ( mode == MBEDTLS_MODE_CBC
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
-#endif
- ) )
- {
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- unsigned char mac[SSL_MAC_MAX_BYTES];
- int ret;
-
- ret = ssl_mac( &ssl->transform_out->md_ctx_enc,
- ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype,
- mac );
-
- if( ret == 0 )
- memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
- mbedtls_platform_zeroize( mac, ssl->transform_out->maclen );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
- return( ret );
- }
- }
- else
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
- {
- unsigned char mac[MBEDTLS_SSL_MAC_ADD];
- int ret;
-
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
- ssl->out_msg, ssl->out_msglen );
- ret = mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
- ret = mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
-
- memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
-
- hmac_failed_etm_disabled:
- mbedtls_platform_zeroize( mac, ssl->transform_out->maclen );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
- return( ret );
- }
- }
- else
-#endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac",
- ssl->out_msg + ssl->out_msglen,
- ssl->transform_out->maclen );
-
- ssl->out_msglen += ssl->transform_out->maclen;
- auth_done++;
- }
-#endif /* AEAD not the only option */
-
- /*
- * Encrypt
- */
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
- if( mode == MBEDTLS_MODE_STREAM )
- {
- int ret;
- size_t olen = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of padding",
- ssl->out_msglen, 0 ) );
-
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
- ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
-
- if( ssl->out_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
-#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
-#if defined(MBEDTLS_GCM_C) || \
- defined(MBEDTLS_CCM_C) || \
- defined(MBEDTLS_CHACHAPOLY_C)
- if( mode == MBEDTLS_MODE_GCM ||
- mode == MBEDTLS_MODE_CCM ||
- mode == MBEDTLS_MODE_CHACHAPOLY )
- {
- int ret;
- size_t enc_msglen, olen;
- unsigned char *enc_msg;
- unsigned char add_data[13];
- unsigned char iv[12];
- mbedtls_ssl_transform *transform = ssl->transform_out;
- unsigned char taglen = transform->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
- size_t explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
-
- /*
- * Prepare additional authenticated data
- */
- memcpy( add_data, ssl->out_ctr, 8 );
- add_data[8] = ssl->out_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, add_data + 9 );
- add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->out_msglen & 0xFF;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 );
-
- /*
- * Generate IV
- */
- if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
- {
- /* GCM and CCM: fixed || explicit (=seqnum) */
- memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
- memcpy( iv + transform->fixed_ivlen, ssl->out_ctr, 8 );
- memcpy( ssl->out_iv, ssl->out_ctr, 8 );
-
- }
- else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
- {
- /* ChachaPoly: fixed XOR sequence number */
- unsigned char i;
-
- memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
-
- for( i = 0; i < 8; i++ )
- iv[i+4] ^= ssl->out_ctr[i];
- }
- else
- {
- /* Reminder if we ever add an AEAD mode with a different size */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
- iv, transform->ivlen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)",
- ssl->out_iv, explicit_ivlen );
-
- /*
- * Fix message length with added IV
- */
- enc_msg = ssl->out_msg;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += explicit_ivlen;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including 0 bytes of padding",
- ssl->out_msglen ) );
-
- /*
- * Encrypt and authenticate
- */
- if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc,
- iv, transform->ivlen,
- add_data, 13,
- enc_msg, enc_msglen,
- enc_msg, &olen,
- enc_msg + enc_msglen, taglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
- return( ret );
- }
-
- if( olen != enc_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->out_msglen += taglen;
- auth_done++;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen );
- }
- else
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
- if( mode == MBEDTLS_MODE_CBC )
- {
- int ret;
- unsigned char *enc_msg;
- size_t enc_msglen, padlen, olen = 0, i;
-
- padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) %
- ssl->transform_out->ivlen;
- if( padlen == ssl->transform_out->ivlen )
- padlen = 0;
-
- for( i = 0; i <= padlen; i++ )
- ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen;
-
- ssl->out_msglen += padlen + 1;
-
- enc_msglen = ssl->out_msglen;
- enc_msg = ssl->out_msg;
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * Prepend per-record IV for block cipher in TLS v1.1 and up as per
- * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Generate IV
- */
- ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen );
- if( ret != 0 )
- return( ret );
-
- memcpy( ssl->out_iv, ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen );
-
- /*
- * Fix pointer positions and message length with added IV
- */
- enc_msg = ssl->out_msg;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += ssl->transform_out->ivlen;
- }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of IV and %d bytes of padding",
- ssl->out_msglen, ssl->transform_out->ivlen,
- padlen + 1 ) );
-
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
- ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen,
- enc_msg, enc_msglen,
- enc_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
-
- if( enc_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Save IV in SSL3 and TLS1
- */
- memcpy( ssl->transform_out->iv_enc,
- ssl->transform_out->cipher_ctx_enc.iv,
- ssl->transform_out->ivlen );
- }
-#endif
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( auth_done == 0 )
- {
- unsigned char mac[MBEDTLS_SSL_MAC_ADD];
-
- /*
- * MAC(MAC_write_key, seq_num +
- * TLSCipherText.type +
- * TLSCipherText.version +
- * length_of( (IV +) ENC(...) ) +
- * IV + // except for TLS 1.0
- * ENC(content + padding + padding_length));
- */
- unsigned char pseudo_hdr[13];
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
-
- memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 );
- memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 );
- pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF );
- pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
-
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
- ssl->out_iv, ssl->out_msglen );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
-
- memcpy( ssl->out_iv + ssl->out_msglen, mac,
- ssl->transform_out->maclen );
-
- ssl->out_msglen += ssl->transform_out->maclen;
- auth_done++;
-
- hmac_failed_etm_enabled:
- mbedtls_platform_zeroize( mac, ssl->transform_out->maclen );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
- return( ret );
- }
- }
-#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- }
- else
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- /* Make extra sure authentication was performed, exactly once */
- if( auth_done != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
-/*
- * Constant-flow conditional memcpy:
- * - if c1 == c2, equivalent to memcpy(dst, src, len),
- * - otherwise, a no-op,
- * but with execution flow independent of the values of c1 and c2.
- *
- * Use only bit operations to avoid branches that could be used by some
- * compilers on some platforms to translate comparison operators.
- */
-static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst,
- const unsigned char *src,
- size_t len,
- size_t c1, size_t c2 )
-{
- /* diff = 0 if c1 == c2, non-zero otherwise */
- const size_t diff = c1 ^ c2;
-
- /* 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
-
- /* diff_msb's most significant bit is equal to c1 != c2 */
- const size_t diff_msb = ( diff | -diff );
-
- /* diff1 = c1 != c2 */
- const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
-
- /* mask = c1 != c2 ? 0xff : 0x00 */
- const unsigned char mask = (unsigned char) -diff1;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- /* dst[i] = c1 != c2 ? dst[i] : src[i] */
- size_t i;
- for( i = 0; i < len; i++ )
- dst[i] = ( dst[i] & mask ) | ( src[i] & ~mask );
-}
-
-/*
- * Compute HMAC of variable-length data with constant flow.
- *
- * Only works with MD-5, SHA-1, SHA-256 and SHA-384.
- * (Otherwise, computation of block_size needs to be adapted.)
- */
-int mbedtls_ssl_cf_hmac(
- mbedtls_md_context_t *ctx,
- const unsigned char *add_data, size_t add_data_len,
- const unsigned char *data, size_t data_len_secret,
- size_t min_data_len, size_t max_data_len,
- unsigned char *output )
-{
- /*
- * This function breaks the HMAC abstraction and uses the md_clone()
- * extension to the MD API in order to get constant-flow behaviour.
- *
- * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
- * concatenation, and okey/ikey are the XOR of the key with some fixed bit
- * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
- *
- * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
- * minlen, then cloning the context, and for each byte up to maxlen
- * finishing up the hash computation, keeping only the correct result.
- *
- * Then we only need to compute HASH(okey + inner_hash) and we're done.
- */
- const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info );
- /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5,
- * all of which have the same block size except SHA-384. */
- const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
- const unsigned char * const ikey = ctx->hmac_ctx;
- const unsigned char * const okey = ikey + block_size;
- const size_t hash_size = mbedtls_md_get_size( ctx->md_info );
-
- unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
- mbedtls_md_context_t aux;
- size_t offset;
- int ret;
-
- mbedtls_md_init( &aux );
-
-#define MD_CHK( func_call ) \
- do { \
- ret = (func_call); \
- if( ret != 0 ) \
- goto cleanup; \
- } while( 0 )
-
- MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) );
-
- /* After hmac_start() of hmac_reset(), ikey has already been hashed,
- * so we can start directly with the message */
- MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
- MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
-
- /* For each possible length, compute the hash up to that point */
- for( offset = min_data_len; offset <= max_data_len; offset++ )
- {
- MD_CHK( mbedtls_md_clone( &aux, ctx ) );
- MD_CHK( mbedtls_md_finish( &aux, aux_out ) );
- /* Keep only the correct inner_hash in the output buffer */
- mbedtls_ssl_cf_memcpy_if_eq( output, aux_out, hash_size,
- offset, data_len_secret );
-
- if( offset < max_data_len )
- MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
- }
-
- /* The context needs to finish() before it starts() again */
- MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
-
- /* Now compute HASH(okey + inner_hash) */
- MD_CHK( mbedtls_md_starts( ctx ) );
- MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
- MD_CHK( mbedtls_md_update( ctx, output, hash_size ) );
- MD_CHK( mbedtls_md_finish( ctx, output ) );
-
- /* Done, get ready for next time */
- MD_CHK( mbedtls_md_hmac_reset( ctx ) );
-
-#undef MD_CHK
-
-cleanup:
- mbedtls_md_free( &aux );
- return( ret );
-}
-
-/*
- * Constant-flow memcpy from variable position in buffer.
- * - functionally equivalent to memcpy(dst, src + offset_secret, len)
- * - but with execution flow independent from the value of offset_secret.
- */
-void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst,
- const unsigned char *src_base,
- size_t offset_secret,
- size_t offset_min, size_t offset_max,
- size_t len )
-{
- size_t offset;
-
- for( offset = offset_min; offset <= offset_max; offset++ )
- {
- mbedtls_ssl_cf_memcpy_if_eq( dst, src_base + offset, len,
- offset, offset_secret );
- }
-}
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
-
-static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
-{
- mbedtls_cipher_mode_t mode;
- int auth_done = 0;
-#if defined(SSL_SOME_MODES_USE_MAC)
- size_t padlen = 0, correct = 1;
-#endif
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
-
- if( ssl->session_in == NULL || ssl->transform_in == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec );
-
- if( ssl->in_msglen < ssl->transform_in->minlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)",
- ssl->in_msglen, ssl->transform_in->minlen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
-
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
- if( mode == MBEDTLS_MODE_STREAM )
- {
- int ret;
- size_t olen = 0;
-
- padlen = 0;
-
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
-
- if( ssl->in_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
-#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
-#if defined(MBEDTLS_GCM_C) || \
- defined(MBEDTLS_CCM_C) || \
- defined(MBEDTLS_CHACHAPOLY_C)
- if( mode == MBEDTLS_MODE_GCM ||
- mode == MBEDTLS_MODE_CCM ||
- mode == MBEDTLS_MODE_CHACHAPOLY )
- {
- int ret;
- size_t dec_msglen, olen;
- unsigned char *dec_msg;
- unsigned char *dec_msg_result;
- unsigned char add_data[13];
- unsigned char iv[12];
- mbedtls_ssl_transform *transform = ssl->transform_in;
- unsigned char taglen = transform->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
- size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen;
-
- /*
- * Compute and update sizes
- */
- if( ssl->in_msglen < explicit_iv_len + taglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) "
- "+ taglen (%d)", ssl->in_msglen,
- explicit_iv_len, taglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- dec_msglen = ssl->in_msglen - explicit_iv_len - taglen;
-
- dec_msg = ssl->in_msg;
- dec_msg_result = ssl->in_msg;
- ssl->in_msglen = dec_msglen;
-
- /*
- * Prepare additional authenticated data
- */
- memcpy( add_data, ssl->in_ctr, 8 );
- add_data[8] = ssl->in_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, add_data + 9 );
- add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->in_msglen & 0xFF;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 );
-
- /*
- * Prepare IV
- */
- if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
- {
- /* GCM and CCM: fixed || explicit (transmitted) */
- memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
- memcpy( iv + transform->fixed_ivlen, ssl->in_iv, 8 );
-
- }
- else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
- {
- /* ChachaPoly: fixed XOR sequence number */
- unsigned char i;
-
- memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
-
- for( i = 0; i < 8; i++ )
- iv[i+4] ^= ssl->in_ctr[i];
- }
- else
- {
- /* Reminder if we ever add an AEAD mode with a different size */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen );
-
- /*
- * Decrypt and authenticate
- */
- if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec,
- iv, transform->ivlen,
- add_data, 13,
- dec_msg, dec_msglen,
- dec_msg_result, &olen,
- dec_msg + dec_msglen, taglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
-
- if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
-
- return( ret );
- }
- auth_done++;
-
- if( olen != dec_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
- if( mode == MBEDTLS_MODE_CBC )
- {
- /*
- * Decrypt and check the padding
- */
- int ret;
- unsigned char *dec_msg;
- unsigned char *dec_msg_result;
- size_t dec_msglen;
- size_t minlen = 0;
- size_t olen = 0;
-
- /*
- * Check immediate ciphertext sanity
- */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- minlen += ssl->transform_in->ivlen;
-#endif
-
- if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
- ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) "
- "+ 1 ) ( + expl IV )", ssl->in_msglen,
- ssl->transform_in->ivlen,
- ssl->transform_in->maclen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
-
- dec_msglen = ssl->in_msglen;
- dec_msg = ssl->in_msg;
- dec_msg_result = ssl->in_msg;
-
- /*
- * Authenticate before decrypt if enabled
- */
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
- {
- unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
- unsigned char pseudo_hdr[13];
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
-
- dec_msglen -= ssl->transform_in->maclen;
- ssl->in_msglen -= ssl->transform_in->maclen;
-
- memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 );
- memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 );
- pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF );
- pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
-
- ret = mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec,
- ssl->in_iv, ssl->in_msglen );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen,
- ssl->transform_in->maclen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
- ssl->transform_in->maclen );
-
- if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect,
- ssl->transform_in->maclen ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
-
- ret = MBEDTLS_ERR_SSL_INVALID_MAC;
- goto hmac_failed_etm_enabled;
- }
- auth_done++;
-
- hmac_failed_etm_enabled:
- mbedtls_platform_zeroize( mac_expect, ssl->transform_in->maclen );
- if( ret != 0 )
- {
- if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret );
- return( ret );
- }
- }
-#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
-
- /*
- * Check length sanity
- */
- if( ssl->in_msglen % ssl->transform_in->ivlen != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
- ssl->in_msglen, ssl->transform_in->ivlen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * Initialize for prepended IV for block cipher in TLS v1.1 and up
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- unsigned char i;
- dec_msglen -= ssl->transform_in->ivlen;
- ssl->in_msglen -= ssl->transform_in->ivlen;
-
- for( i = 0; i < ssl->transform_in->ivlen; i++ )
- ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
- }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
-
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- dec_msg, dec_msglen,
- dec_msg_result, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
-
- if( dec_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Save IV in SSL3 and TLS1
- */
- memcpy( ssl->transform_in->iv_dec,
- ssl->transform_in->cipher_ctx_dec.iv,
- ssl->transform_in->ivlen );
- }
-#endif
-
- padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
-
- if( ssl->in_msglen < ssl->transform_in->maclen + padlen &&
- auth_done == 0 )
- {
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
- ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
-#endif
- padlen = 0;
- correct = 0;
- }
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( padlen > ssl->transform_in->ivlen )
- {
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
- "should be no more than %d",
- padlen, ssl->transform_in->ivlen ) );
-#endif
- correct = 0;
- }
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- /*
- * TLSv1+: always check the padding up to the first failure
- * and fake check up to 256 bytes of padding
- */
- size_t pad_count = 0, real_count = 1;
- size_t padding_idx = ssl->in_msglen - padlen;
- size_t i;
-
- /*
- * Padding is guaranteed to be incorrect if:
- * 1. padlen > ssl->in_msglen
- *
- * 2. padding_idx > MBEDTLS_SSL_IN_CONTENT_LEN +
- * ssl->transform_in->maclen
- *
- * In both cases we reset padding_idx to a safe value (0) to
- * prevent out-of-buffer reads.
- */
- correct &= ( padlen <= ssl->in_msglen );
- correct &= ( padding_idx <= MBEDTLS_SSL_IN_CONTENT_LEN +
- ssl->transform_in->maclen );
-
- padding_idx *= correct;
-
- for( i = 0; i < 256; i++ )
- {
- real_count &= ( i < padlen );
- pad_count += real_count *
- ( ssl->in_msg[padding_idx + i] == padlen - 1 );
- }
-
- correct &= ( pad_count == padlen ); /* Only 1 on correct padding */
-
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- if( padlen > 0 && correct == 0 )
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
-#endif
- padlen &= correct * 0x1FF;
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->in_msglen -= padlen;
- }
- else
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
- ssl->in_msg, ssl->in_msglen );
-#endif
-
- /*
- * Authenticate if not done yet.
- * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
- */
-#if defined(SSL_SOME_MODES_USE_MAC)
- if( auth_done == 0 )
- {
- unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
- unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
- int ret = 0;
-
- ssl->in_msglen -= ssl->transform_in->maclen;
-
- ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 );
- ssl->in_len[1] = (unsigned char)( ssl->in_msglen );
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- ret = ssl_mac( &ssl->transform_in->md_ctx_dec,
- ssl->transform_in->mac_dec,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_ctr, ssl->in_msgtype,
- mac_expect );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
- return( ret );
- }
- memcpy( mac_peer, ssl->in_msg + ssl->in_msglen,
- ssl->transform_in->maclen );
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- unsigned char add_data[13];
-
- /*
- * The next two sizes are the minimum and maximum values of
- * in_msglen over all padlen values.
- *
- * They're independent of padlen, since we previously did
- * in_msglen -= padlen.
- *
- * Note that max_len + maclen is never more than the buffer
- * length, as we previously did in_msglen -= maclen too.
- */
- const size_t max_len = ssl->in_msglen + padlen;
- const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
-
- memcpy( add_data + 0, ssl->in_ctr, 8 );
- memcpy( add_data + 8, ssl->in_hdr, 3 );
- memcpy( add_data + 11, ssl->in_len, 2 );
-
- ret = mbedtls_ssl_cf_hmac( &ssl->transform_in->md_ctx_dec,
- add_data, sizeof( add_data ),
- ssl->in_msg, ssl->in_msglen,
- min_len, max_len,
- mac_expect );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret );
- goto hmac_failed_etm_disabled;
- }
-
- mbedtls_ssl_cf_memcpy_offset( mac_peer, ssl->in_msg,
- ssl->in_msglen,
- min_len, max_len,
- ssl->transform_in->maclen );
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, ssl->transform_in->maclen );
-#endif
-
- if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect,
- ssl->transform_in->maclen ) != 0 )
- {
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
-#endif
- correct = 0;
- }
- auth_done++;
-
- hmac_failed_etm_disabled:
- mbedtls_platform_zeroize( mac_peer, ssl->transform_in->maclen );
- mbedtls_platform_zeroize( mac_expect, ssl->transform_in->maclen );
- if( ret != 0 )
- return( ret );
- }
-
- /*
- * 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 */
- if( auth_done != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- if( ssl->in_msglen == 0 )
- {
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
- && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
- ssl->nb_zero++;
-
- /*
- * Three or more empty messages may be a DoS attack
- * (excessive CPU consumption).
- */
- if( ssl->nb_zero > 3 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
- "messages, possible DoS attack" ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- }
- else
- ssl->nb_zero = 0;
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ; /* in_ctr read from peer, not maintained internally */
- }
- else
-#endif
- {
- unsigned char i;
- for( i = 8; i > ssl_ep_len( ssl ); i-- )
- if( ++ssl->in_ctr[i - 1] != 0 )
- break;
-
- /* The loop goes to its end iff the counter is wrapping */
- if( i == ssl_ep_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
-
- return( 0 );
-}
-
-#undef MAC_NONE
-#undef MAC_PLAINTEXT
-#undef MAC_CIPHERTEXT
-
-#if defined(MBEDTLS_ZLIB_SUPPORT)
-/*
- * Compression/decompression functions
- */
-static int ssl_compress_buf( mbedtls_ssl_context *ssl )
-{
- int ret;
- unsigned char *msg_post = ssl->out_msg;
- ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
- size_t len_pre = ssl->out_msglen;
- unsigned char *msg_pre = ssl->compress_buf;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
-
- if( len_pre == 0 )
- return( 0 );
-
- memcpy( msg_pre, ssl->out_msg, len_pre );
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ",
- ssl->out_msglen ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
- ssl->out_msg, ssl->out_msglen );
-
- ssl->transform_out->ctx_deflate.next_in = msg_pre;
- ssl->transform_out->ctx_deflate.avail_in = len_pre;
- ssl->transform_out->ctx_deflate.next_out = msg_post;
- ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written;
-
- ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
- if( ret != Z_OK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
- }
-
- ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN -
- ssl->transform_out->ctx_deflate.avail_out - bytes_written;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
- ssl->out_msglen ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
- ssl->out_msg, ssl->out_msglen );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
-
- return( 0 );
-}
-
-static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
-{
- int ret;
- unsigned char *msg_post = ssl->in_msg;
- ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
- size_t len_pre = ssl->in_msglen;
- unsigned char *msg_pre = ssl->compress_buf;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
-
- if( len_pre == 0 )
- return( 0 );
-
- memcpy( msg_pre, ssl->in_msg, len_pre );
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ",
- ssl->in_msglen ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
- ssl->in_msg, ssl->in_msglen );
-
- ssl->transform_in->ctx_inflate.next_in = msg_pre;
- ssl->transform_in->ctx_inflate.avail_in = len_pre;
- ssl->transform_in->ctx_inflate.next_out = msg_post;
- ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN -
- header_bytes;
-
- ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
- if( ret != Z_OK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
- }
-
- ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN -
- ssl->transform_in->ctx_inflate.avail_out - header_bytes;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
- ssl->in_msglen ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
- ssl->in_msg, ssl->in_msglen );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
-
- return( 0 );
-}
-#endif /* MBEDTLS_ZLIB_SUPPORT */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
-static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_resend_hello_request( mbedtls_ssl_context *ssl )
{
/* If renegotiation is not enforced, retransmit until we would reach max
* timeout if we were using the usual handshake doubling scheme */
@@ -2777,2795 +2138,42 @@ static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
#endif
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
-/*
- * Fill the input message buffer by appending data to it.
- * The amount of data already fetched is in ssl->in_left.
- *
- * If we return 0, is it guaranteed that (at least) nb_want bytes are
- * available (from this read and/or a previous one). Otherwise, an error code
- * is returned (possibly EOF or WANT_READ).
- *
- * With stream transport (TLS) on success ssl->in_left == nb_want, but
- * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
- * since we always read a whole datagram at once.
- *
- * For DTLS, it is up to the caller to set ssl->next_record_offset when
- * they're done reading a record.
- */
-int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
-{
- int ret;
- size_t len;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
-
- if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
- "or mbedtls_ssl_set_bio()" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
- if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- uint32_t timeout;
-
- /* Just to be sure */
- if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
- "mbedtls_ssl_set_timer_cb() for DTLS" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
- /*
- * The point is, we need to always read a full datagram at once, so we
- * sometimes read more then requested, and handle the additional data.
- * It could be the rest of the current record (while fetching the
- * header) and/or some other records in the same datagram.
- */
-
- /*
- * Move to the next record in the already read datagram if applicable
- */
- if( ssl->next_record_offset != 0 )
- {
- if( ssl->in_left < ssl->next_record_offset )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->in_left -= ssl->next_record_offset;
-
- if( ssl->in_left != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d",
- ssl->next_record_offset ) );
- memmove( ssl->in_hdr,
- ssl->in_hdr + ssl->next_record_offset,
- ssl->in_left );
- }
-
- ssl->next_record_offset = 0;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
-
- /*
- * Done if we already have enough data.
- */
- if( nb_want <= ssl->in_left)
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
- return( 0 );
- }
-
- /*
- * A record can't be split across datagrams. If we need to read but
- * are not at the beginning of a new record, the caller did something
- * wrong.
- */
- if( ssl->in_left != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- /*
- * Don't even try to read if time's out already.
- * This avoids by-passing the timer when repeatedly receiving messages
- * that will end up being dropped.
- */
- if( ssl_check_timer( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) );
- ret = MBEDTLS_ERR_SSL_TIMEOUT;
- }
- else
- {
- len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
-
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- timeout = ssl->handshake->retransmit_timeout;
- else
- timeout = ssl->conf->read_timeout;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
-
- if( ssl->f_recv_timeout != NULL )
- ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
- timeout );
- else
- ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
-
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
-
- if( ret == 0 )
- return( MBEDTLS_ERR_SSL_CONN_EOF );
- }
-
- if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
- ssl_set_timer( ssl, 0 );
-
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- if( ssl_double_retransmit_timeout( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
- return( MBEDTLS_ERR_SSL_TIMEOUT );
- }
-
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
- return( ret );
- }
-
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
-#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
- else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
- return( ret );
- }
-
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
-#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
- }
-
- if( ret < 0 )
- return( ret );
-
- ssl->in_left = ret;
- }
- else
-#endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
-
- while( ssl->in_left < nb_want )
- {
- len = nb_want - ssl->in_left;
-
- if( ssl_check_timer( ssl ) != 0 )
- ret = MBEDTLS_ERR_SSL_TIMEOUT;
- else
- {
- if( ssl->f_recv_timeout != NULL )
- {
- ret = ssl->f_recv_timeout( ssl->p_bio,
- ssl->in_hdr + ssl->in_left, len,
- ssl->conf->read_timeout );
- }
- else
- {
- ret = ssl->f_recv( ssl->p_bio,
- ssl->in_hdr + ssl->in_left, len );
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
-
- if( ret == 0 )
- return( MBEDTLS_ERR_SSL_CONN_EOF );
-
- if( ret < 0 )
- return( ret );
-
- if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1,
- ( "f_recv returned %d bytes but only %lu were requested",
- ret, (unsigned long)len ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->in_left += ret;
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
-
- return( 0 );
-}
-
-/*
- * Flush any data not yet written
- */
-int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
-{
- int ret;
- unsigned char *buf;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
-
- if( ssl->f_send == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
- "or mbedtls_ssl_set_bio()" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
- /* Avoid incrementing counter if data is flushed */
- if( ssl->out_left == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
- return( 0 );
- }
-
- while( ssl->out_left > 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
- mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
-
- buf = ssl->out_hdr - ssl->out_left;
- ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
-
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
-
- if( ret <= 0 )
- return( ret );
-
- if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1,
- ( "f_send returned %d bytes but only %lu bytes were sent",
- ret, (unsigned long)ssl->out_left ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->out_left -= ret;
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->out_hdr = ssl->out_buf;
- }
- else
-#endif
- {
- ssl->out_hdr = ssl->out_buf + 8;
- }
- ssl_update_out_pointers( ssl, ssl->transform_out );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
-
- return( 0 );
-}
-
-/*
- * Functions to handle the DTLS retransmission state machine
- */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-/*
- * Append current handshake message to current outgoing flight
- */
-static int ssl_flight_append( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_flight_item *msg;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
- ssl->out_msg, ssl->out_msglen );
-
- /* Allocate space for current message */
- if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed",
- sizeof( mbedtls_ssl_flight_item ) ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
-
- if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) );
- mbedtls_free( msg );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
-
- /* Copy current handshake message with headers */
- memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
- msg->len = ssl->out_msglen;
- msg->type = ssl->out_msgtype;
- msg->next = NULL;
-
- /* Append to the current flight */
- if( ssl->handshake->flight == NULL )
- ssl->handshake->flight = msg;
- else
- {
- mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
- while( cur->next != NULL )
- cur = cur->next;
- cur->next = msg;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
- return( 0 );
-}
-
-/*
- * Free the current flight of handshake messages
- */
-static void ssl_flight_free( mbedtls_ssl_flight_item *flight )
-{
- mbedtls_ssl_flight_item *cur = flight;
- mbedtls_ssl_flight_item *next;
-
- while( cur != NULL )
- {
- next = cur->next;
-
- mbedtls_free( cur->p );
- mbedtls_free( cur );
-
- cur = next;
- }
-}
-
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
-#endif
-
-/*
- * Swap transform_out and out_ctr with the alternative ones
- */
-static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_transform *tmp_transform;
- unsigned char tmp_out_ctr[8];
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- int ret;
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
-
- if( ssl->transform_out == ssl->handshake->alt_transform_out )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
- return( 0 );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
-
- /* Swap transforms */
- tmp_transform = ssl->transform_out;
- ssl->transform_out = ssl->handshake->alt_transform_out;
- ssl->handshake->alt_transform_out = tmp_transform;
-
- /* Swap epoch + sequence_number */
- memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
- memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
- memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
-
- /* Adjust to the newly activated transform */
- ssl_update_out_pointers( ssl, ssl->transform_out );
-
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_activate != NULL )
- {
- if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- }
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
-
- return( 0 );
-}
-
-/*
- * Retransmit the current flight of messages.
- */
-int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
-{
- int ret = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
-
- ret = mbedtls_ssl_flight_transmit( ssl );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
-
- return( ret );
-}
-
-/*
- * Transmit or retransmit the current flight of messages.
- *
- * Need to remember the current message in case flush_output returns
- * WANT_WRITE, causing us to exit this function and come back later.
- * This function must be called until state is no longer SENDING.
- */
-int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
-{
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
-
- if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) );
-
- ssl->handshake->cur_msg = ssl->handshake->flight;
- ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
- if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
- return( ret );
-
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
- }
-
- while( ssl->handshake->cur_msg != NULL )
- {
- size_t max_frag_len;
- const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
-
- int const is_finished =
- ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
- cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
-
- uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
- SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
-
- /* Swap epochs before sending Finished: we can't do it after
- * sending ChangeCipherSpec, in case write returns WANT_READ.
- * Must be done before copying, may change out_msg pointer */
- if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
- if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
- return( ret );
- }
-
- ret = ssl_get_remaining_payload_in_datagram( ssl );
- if( ret < 0 )
- return( ret );
- max_frag_len = (size_t) ret;
-
- /* CCS is copied as is, while HS messages may need fragmentation */
- if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
- {
- if( max_frag_len == 0 )
- {
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- continue;
- }
-
- memcpy( ssl->out_msg, cur->p, cur->len );
- ssl->out_msglen = cur->len;
- ssl->out_msgtype = cur->type;
-
- /* Update position inside current message */
- ssl->handshake->cur_msg_p += cur->len;
- }
- else
- {
- const unsigned char * const p = ssl->handshake->cur_msg_p;
- const size_t hs_len = cur->len - 12;
- const size_t frag_off = p - ( cur->p + 12 );
- const size_t rem_len = hs_len - frag_off;
- size_t cur_hs_frag_len, max_hs_frag_len;
-
- if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
- {
- if( is_finished )
- {
- if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
- return( ret );
- }
-
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- continue;
- }
- max_hs_frag_len = max_frag_len - 12;
-
- cur_hs_frag_len = rem_len > max_hs_frag_len ?
- max_hs_frag_len : rem_len;
-
- if( frag_off == 0 && cur_hs_frag_len != hs_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
- (unsigned) cur_hs_frag_len,
- (unsigned) max_hs_frag_len ) );
- }
-
- /* Messages are stored with handshake headers as if not fragmented,
- * copy beginning of headers then fill fragmentation fields.
- * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
- memcpy( ssl->out_msg, cur->p, 6 );
-
- ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff );
- ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff );
- ssl->out_msg[8] = ( ( frag_off ) & 0xff );
-
- ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff );
- ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff );
- ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff );
-
- MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
-
- /* Copy the handshake message content and set records fields */
- memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
- ssl->out_msglen = cur_hs_frag_len + 12;
- ssl->out_msgtype = cur->type;
-
- /* Update position inside current message */
- ssl->handshake->cur_msg_p += cur_hs_frag_len;
- }
-
- /* If done with the current message move to the next one if any */
- if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
- {
- if( cur->next != NULL )
- {
- ssl->handshake->cur_msg = cur->next;
- ssl->handshake->cur_msg_p = cur->next->p + 12;
- }
- else
- {
- ssl->handshake->cur_msg = NULL;
- ssl->handshake->cur_msg_p = NULL;
- }
- }
-
- /* Actually send the message out */
- if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- }
-
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- /* Update state and set timer */
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- else
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
- ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
-
- return( 0 );
-}
-
-/*
- * To be called when the last message of an incoming flight is received.
- */
-void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
-{
- /* We won't need to resend that one any more */
- ssl_flight_free( ssl->handshake->flight );
- ssl->handshake->flight = NULL;
- ssl->handshake->cur_msg = NULL;
-
- /* The next incoming flight will start with this msg_seq */
- ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
-
- /* We don't want to remember CCS's across flight boundaries. */
- ssl->handshake->buffering.seen_ccs = 0;
-
- /* Clear future message buffering structure. */
- ssl_buffering_free( ssl );
-
- /* Cancel timer */
- ssl_set_timer( ssl, 0 );
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- }
- else
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
-}
-
-/*
- * To be called when the last message of an outgoing flight is send.
- */
-void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
-{
- ssl_reset_retransmit_timeout( ssl );
- ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- }
- else
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
-}
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-/*
- * Handshake layer functions
- */
-
-/*
- * Write (DTLS: or queue) current handshake (including CCS) message.
- *
- * - fill in handshake headers
- * - update handshake checksum
- * - DTLS: save message for resending
- * - then pass to the record layer
- *
- * DTLS: except for HelloRequest, messages are only queued, and will only be
- * actually sent when calling flight_transmit() or resend().
- *
- * Inputs:
- * - ssl->out_msglen: 4 + actual handshake message len
- * (4 is the size of handshake headers for TLS)
- * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
- * - ssl->out_msg + 4: the handshake message body
- *
- * Outputs, ie state before passing to flight_append() or write_record():
- * - ssl->out_msglen: the length of the record contents
- * (including handshake headers but excluding record headers)
- * - ssl->out_msg: the record contents (handshake headers + content)
- */
-int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
-{
- int ret;
- const size_t hs_len = ssl->out_msglen - 4;
- const unsigned char hs_type = ssl->out_msg[0];
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) );
-
- /*
- * Sanity checks
- */
- if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
- {
- /* In SSLv3, the client might send a NoCertificate alert. */
-#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
- if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
- ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT &&
- ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) )
-#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
-
- /* Whenever we send anything different from a
- * HelloRequest we should be in a handshake - double check. */
- if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
- ssl->handshake == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-#endif
-
- /* Double-check that we did not exceed the bounds
- * of the outgoing record buffer.
- * This should never fail as the various message
- * writing functions must obey the bounds of the
- * outgoing record buffer, but better be safe.
- *
- * Note: We deliberately do not check for the MTU or MFL here.
- */
- if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
- "size %u, maximum %u",
- (unsigned) ssl->out_msglen,
- (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- /*
- * Fill handshake headers
- */
- if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- ssl->out_msg[1] = (unsigned char)( hs_len >> 16 );
- ssl->out_msg[2] = (unsigned char)( hs_len >> 8 );
- ssl->out_msg[3] = (unsigned char)( hs_len );
-
- /*
- * DTLS has additional fields in the Handshake layer,
- * between the length field and the actual payload:
- * uint16 message_seq;
- * uint24 fragment_offset;
- * uint24 fragment_length;
- */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Make room for the additional DTLS fields */
- if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
- "size %u, maximum %u",
- (unsigned) ( hs_len ),
- (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
- memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len );
- ssl->out_msglen += 8;
-
- /* Write message_seq and update it, except for HelloRequest */
- if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
- {
- ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
- ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF;
- ++( ssl->handshake->out_msg_seq );
- }
- else
- {
- ssl->out_msg[4] = 0;
- ssl->out_msg[5] = 0;
- }
-
- /* Handshake hashes are computed without fragmentation,
- * so set frag_offset = 0 and frag_len = hs_len for now */
- memset( ssl->out_msg + 6, 0x00, 3 );
- memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- /* Update running hashes of handshake messages seen */
- if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
- ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
- }
-
- /* Either send now, or just save to be sent (and resent) later */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
- {
- if( ( ret = ssl_flight_append( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
- return( ret );
- }
- }
- else
-#endif
- {
- if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
- return( ret );
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
-
- return( 0 );
-}
-
-/*
- * Record layer functions
- */
-
-/*
- * Write current record.
- *
- * Uses:
- * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
- * - ssl->out_msglen: length of the record content (excl headers)
- * - ssl->out_msg: record content
- */
-int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
-{
- int ret, done = 0;
- size_t len = ssl->out_msglen;
- uint8_t flush = force_flush;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
-
-#if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->transform_out != NULL &&
- ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
- {
- if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
- return( ret );
- }
-
- len = ssl->out_msglen;
- }
-#endif /*MBEDTLS_ZLIB_SUPPORT */
-
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_write != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
-
- ret = mbedtls_ssl_hw_record_write( ssl );
- if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
-
- if( ret == 0 )
- done = 1;
- }
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- if( !done )
- {
- unsigned i;
- size_t protected_record_size;
-
- ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, ssl->out_hdr + 1 );
-
- memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
- ssl->out_len[0] = (unsigned char)( len >> 8 );
- ssl->out_len[1] = (unsigned char)( len );
-
- if( ssl->transform_out != NULL )
- {
- if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
- return( ret );
- }
-
- len = ssl->out_msglen;
- ssl->out_len[0] = (unsigned char)( len >> 8 );
- ssl->out_len[1] = (unsigned char)( len );
- }
-
- protected_record_size = len + mbedtls_ssl_hdr_len( ssl );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* In case of DTLS, double-check that we don't exceed
- * the remaining space in the datagram. */
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ret = ssl_get_remaining_space_in_datagram( ssl );
- if( ret < 0 )
- return( ret );
-
- if( protected_record_size > (size_t) ret )
- {
- /* Should never happen */
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
- "version = [%d:%d], msglen = %d",
- ssl->out_hdr[0], ssl->out_hdr[1],
- ssl->out_hdr[2], len ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
- ssl->out_hdr, protected_record_size );
-
- ssl->out_left += protected_record_size;
- ssl->out_hdr += protected_record_size;
- ssl_update_out_pointers( ssl, ssl->transform_out );
-
- for( i = 8; i > ssl_ep_len( ssl ); i-- )
- if( ++ssl->cur_out_ctr[i - 1] != 0 )
- break;
-
- /* The loop goes to its end iff the counter is wrapping */
- if( i == ssl_ep_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- flush == SSL_DONT_FORCE_FLUSH )
- {
- size_t remaining;
- ret = ssl_get_remaining_payload_in_datagram( ssl );
- if( ret < 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
- ret );
- return( ret );
- }
-
- remaining = (size_t) ret;
- if( remaining == 0 )
- {
- flush = SSL_FORCE_FLUSH;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- if( ( flush == SSL_FORCE_FLUSH ) &&
- ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
- return( ret );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-
-static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
-{
- if( ssl->in_msglen < ssl->in_hslen ||
- memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
- memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
- {
- return( 1 );
- }
- return( 0 );
-}
-
-static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl )
-{
- return( ( ssl->in_msg[9] << 16 ) |
- ( ssl->in_msg[10] << 8 ) |
- ssl->in_msg[11] );
-}
-
-static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
-{
- return( ( ssl->in_msg[6] << 16 ) |
- ( ssl->in_msg[7] << 8 ) |
- ssl->in_msg[8] );
-}
-
-static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
-{
- uint32_t msg_len, frag_off, frag_len;
-
- msg_len = ssl_get_hs_total_len( ssl );
- frag_off = ssl_get_hs_frag_off( ssl );
- frag_len = ssl_get_hs_frag_len( ssl );
-
- if( frag_off > msg_len )
- return( -1 );
-
- if( frag_len > msg_len - frag_off )
- return( -1 );
-
- if( frag_len + 12 > ssl->in_msglen )
- return( -1 );
-
- return( 0 );
-}
-
-/*
- * Mark bits in bitmask (used for DTLS HS reassembly)
- */
-static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
-{
- unsigned int start_bits, end_bits;
-
- start_bits = 8 - ( offset % 8 );
- if( start_bits != 8 )
- {
- size_t first_byte_idx = offset / 8;
-
- /* Special case */
- if( len <= start_bits )
- {
- for( ; len != 0; len-- )
- mask[first_byte_idx] |= 1 << ( start_bits - len );
-
- /* Avoid potential issues with offset or len becoming invalid */
- return;
- }
-
- offset += start_bits; /* Now offset % 8 == 0 */
- len -= start_bits;
-
- for( ; start_bits != 0; start_bits-- )
- mask[first_byte_idx] |= 1 << ( start_bits - 1 );
- }
-
- end_bits = len % 8;
- if( end_bits != 0 )
- {
- size_t last_byte_idx = ( offset + len ) / 8;
-
- len -= end_bits; /* Now len % 8 == 0 */
-
- for( ; end_bits != 0; end_bits-- )
- mask[last_byte_idx] |= 1 << ( 8 - end_bits );
- }
-
- memset( mask + offset / 8, 0xFF, len / 8 );
-}
-
-/*
- * Check that bitmask is full
- */
-static int ssl_bitmask_check( unsigned char *mask, size_t len )
-{
- size_t i;
-
- for( i = 0; i < len / 8; i++ )
- if( mask[i] != 0xFF )
- return( -1 );
-
- for( i = 0; i < len % 8; i++ )
- if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
- return( -1 );
-
- return( 0 );
-}
-
-/* msg_len does not include the handshake header */
-static size_t ssl_get_reassembly_buffer_size( size_t msg_len,
- unsigned add_bitmap )
-{
- size_t alloc_len;
-
- alloc_len = 12; /* Handshake header */
- alloc_len += msg_len; /* Content buffer */
-
- if( add_bitmap )
- alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */
-
- return( alloc_len );
-}
-
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl )
-{
- return( ( ssl->in_msg[1] << 16 ) |
- ( ssl->in_msg[2] << 8 ) |
- ssl->in_msg[3] );
-}
-
-int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
-{
- if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d",
- ssl->in_msglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl );
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
- " %d, type = %d, hslen = %d",
- ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- int ret;
- unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
-
- if( ssl_check_hs_header( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- if( ssl->handshake != NULL &&
- ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
- recv_msg_seq != ssl->handshake->in_msg_seq ) ||
- ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
- ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) )
- {
- if( recv_msg_seq > ssl->handshake->in_msg_seq )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)",
- recv_msg_seq,
- ssl->handshake->in_msg_seq ) );
- return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
- }
-
- /* Retransmit only on last message from previous flight, to avoid
- * too many retransmissions.
- * Besides, No sane server ever retransmits HelloVerifyRequest */
- if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
- ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
- "message_seq = %d, start_of_flight = %d",
- recv_msg_seq,
- ssl->handshake->in_flight_start_seq ) );
-
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
- return( ret );
- }
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
- "message_seq = %d, expected = %d",
- recv_msg_seq,
- ssl->handshake->in_msg_seq ) );
- }
-
- return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
- }
- /* Wait until message completion to increment in_msg_seq */
-
- /* Message reassembly is handled alongside buffering of future
- * messages; the commonality is that both handshake fragments and
- * future messages cannot be forwarded immediately to the
- * handshake logic layer. */
- if( ssl_hs_is_proper_fragment( ssl ) == 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
- return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
- }
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- /* With TLS we don't handle fragmentation (for now) */
- if( ssl->in_msglen < ssl->in_hslen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
-
- return( 0 );
-}
-
-void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
-
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
- {
- ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
- }
-
- /* Handshake message is complete, increment counter */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL )
- {
- unsigned offset;
- mbedtls_ssl_hs_buffer *hs_buf;
-
- /* Increment handshake sequence number */
- hs->in_msg_seq++;
-
- /*
- * Clear up handshake buffering and reassembly structure.
- */
-
- /* Free first entry */
- ssl_buffering_free_slot( ssl, 0 );
-
- /* Shift all other entries */
- for( offset = 0, hs_buf = &hs->buffering.hs[0];
- offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
- offset++, hs_buf++ )
- {
- *hs_buf = *(hs_buf + 1);
- }
-
- /* Create a fresh last entry */
- memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
- }
-#endif
-}
-
-/*
- * DTLS anti-replay: RFC 6347 4.1.2.6
- *
- * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
- * Bit n is set iff record number in_window_top - n has been seen.
- *
- * Usually, in_window_top is the last record number seen and the lsb of
- * in_window is set. The only exception is the initial state (record number 0
- * not seen yet).
- */
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
-{
- ssl->in_window_top = 0;
- ssl->in_window = 0;
-}
-
-static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
-{
- return( ( (uint64_t) buf[0] << 40 ) |
- ( (uint64_t) buf[1] << 32 ) |
- ( (uint64_t) buf[2] << 24 ) |
- ( (uint64_t) buf[3] << 16 ) |
- ( (uint64_t) buf[4] << 8 ) |
- ( (uint64_t) buf[5] ) );
-}
-
-/*
- * Return 0 if sequence number is acceptable, -1 otherwise
- */
-int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl )
-{
- uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
- uint64_t bit;
-
- if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
- return( 0 );
-
- if( rec_seqnum > ssl->in_window_top )
- return( 0 );
-
- bit = ssl->in_window_top - rec_seqnum;
-
- if( bit >= 64 )
- return( -1 );
-
- if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
- return( -1 );
-
- return( 0 );
-}
-
-/*
- * Update replay window on new validated record
- */
-void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
-{
- uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
-
- if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
- return;
-
- if( rec_seqnum > ssl->in_window_top )
- {
- /* Update window_top and the contents of the window */
- uint64_t shift = rec_seqnum - ssl->in_window_top;
-
- if( shift >= 64 )
- ssl->in_window = 1;
- else
- {
- ssl->in_window <<= shift;
- ssl->in_window |= 1;
- }
-
- ssl->in_window_top = rec_seqnum;
- }
- else
- {
- /* Mark that number as seen in the current window */
- uint64_t bit = ssl->in_window_top - rec_seqnum;
-
- if( bit < 64 ) /* Always true, but be extra sure */
- ssl->in_window |= (uint64_t) 1 << bit;
- }
-}
-#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
-
-#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
-/* Forward declaration */
-static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
-
-/*
- * Without any SSL context, check if a datagram looks like a ClientHello with
- * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
- * Both input and output include full DTLS headers.
- *
- * - if cookie is valid, return 0
- * - if ClientHello looks superficially valid but cookie is not,
- * fill obuf and set olen, then
- * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
- * - otherwise return a specific error code
- */
-static int ssl_check_dtls_clihlo_cookie(
- mbedtls_ssl_cookie_write_t *f_cookie_write,
- mbedtls_ssl_cookie_check_t *f_cookie_check,
- void *p_cookie,
- const unsigned char *cli_id, size_t cli_id_len,
- const unsigned char *in, size_t in_len,
- unsigned char *obuf, size_t buf_len, size_t *olen )
-{
- size_t sid_len, cookie_len;
- unsigned char *p;
-
- if( f_cookie_write == NULL || f_cookie_check == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- /*
- * Structure of ClientHello with record and handshake headers,
- * and expected values. We don't need to check a lot, more checks will be
- * done when actually parsing the ClientHello - skipping those checks
- * avoids code duplication and does not make cookie forging any easier.
- *
- * 0-0 ContentType type; copied, must be handshake
- * 1-2 ProtocolVersion version; copied
- * 3-4 uint16 epoch; copied, must be 0
- * 5-10 uint48 sequence_number; copied
- * 11-12 uint16 length; (ignored)
- *
- * 13-13 HandshakeType msg_type; (ignored)
- * 14-16 uint24 length; (ignored)
- * 17-18 uint16 message_seq; copied
- * 19-21 uint24 fragment_offset; copied, must be 0
- * 22-24 uint24 fragment_length; (ignored)
- *
- * 25-26 ProtocolVersion client_version; (ignored)
- * 27-58 Random random; (ignored)
- * 59-xx SessionID session_id; 1 byte len + sid_len content
- * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
- * ...
- *
- * Minimum length is 61 bytes.
- */
- if( in_len < 61 ||
- in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
- in[3] != 0 || in[4] != 0 ||
- in[19] != 0 || in[20] != 0 || in[21] != 0 )
- {
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
-
- sid_len = in[59];
- if( sid_len > in_len - 61 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
-
- cookie_len = in[60 + sid_len];
- if( cookie_len > in_len - 60 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
-
- if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
- cli_id, cli_id_len ) == 0 )
- {
- /* Valid cookie */
- return( 0 );
- }
-
- /*
- * If we get here, we've got an invalid cookie, let's prepare HVR.
- *
- * 0-0 ContentType type; copied
- * 1-2 ProtocolVersion version; copied
- * 3-4 uint16 epoch; copied
- * 5-10 uint48 sequence_number; copied
- * 11-12 uint16 length; olen - 13
- *
- * 13-13 HandshakeType msg_type; hello_verify_request
- * 14-16 uint24 length; olen - 25
- * 17-18 uint16 message_seq; copied
- * 19-21 uint24 fragment_offset; copied
- * 22-24 uint24 fragment_length; olen - 25
- *
- * 25-26 ProtocolVersion server_version; 0xfe 0xff
- * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
- *
- * Minimum length is 28.
- */
- if( buf_len < 28 )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-
- /* Copy most fields and adapt others */
- memcpy( obuf, in, 25 );
- obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
- obuf[25] = 0xfe;
- obuf[26] = 0xff;
-
- /* Generate and write actual cookie */
- p = obuf + 28;
- if( f_cookie_write( p_cookie,
- &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
- {
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- *olen = p - obuf;
-
- /* Go back and fill length fields */
- obuf[27] = (unsigned char)( *olen - 28 );
-
- obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 );
- obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 );
- obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) );
-
- obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 );
- obuf[12] = (unsigned char)( ( *olen - 13 ) );
-
- return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
-}
-
-/*
- * Handle possible client reconnect with the same UDP quadruplet
- * (RFC 6347 Section 4.2.8).
- *
- * Called by ssl_parse_record_header() in case we receive an epoch 0 record
- * that looks like a ClientHello.
- *
- * - if the input looks like a ClientHello without cookies,
- * send back HelloVerifyRequest, then
- * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
- * - if the input looks like a ClientHello with a valid cookie,
- * reset the session of the current context, and
- * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
- * - if anything goes wrong, return a specific error code
- *
- * mbedtls_ssl_read_record() will ignore the record if anything else than
- * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function
- * cannot not return 0.
- */
-static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
-{
- int ret;
- size_t len;
-
- ret = ssl_check_dtls_clihlo_cookie(
- ssl->conf->f_cookie_write,
- ssl->conf->f_cookie_check,
- ssl->conf->p_cookie,
- ssl->cli_id, ssl->cli_id_len,
- ssl->in_buf, ssl->in_left,
- ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
-
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
-
- if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
- {
- int send_ret;
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
- ssl->out_buf, len );
- /* Don't check write errors as we can't do anything here.
- * If the error is permanent we'll catch it later,
- * if it's not, then hopefully it'll work next time. */
- send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
- (void) send_ret;
-
- return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
- }
-
- if( ret == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
- if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
- return( ret );
- }
-
- return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
- }
-
- return( ret );
-}
-#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
-
-/*
- * ContentType type;
- * ProtocolVersion version;
- * uint16 epoch; // DTLS only
- * uint48 sequence_number; // DTLS only
- * uint16 length;
- *
- * Return 0 if header looks sane (and, for DTLS, the record is expected)
- * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
- * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
- *
- * With DTLS, mbedtls_ssl_read_record() will:
- * 1. proceed with the record if this function returns 0
- * 2. drop only the current record if this function returns UNEXPECTED_RECORD
- * 3. return CLIENT_RECONNECT if this function return that value
- * 4. drop the whole datagram if this function returns anything else.
- * Point 2 is needed when the peer is resending, and we have already received
- * the first record from a datagram but are still waiting for the others.
- */
-static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
-{
- int major_ver, minor_ver;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) );
-
- ssl->in_msgtype = ssl->in_hdr[0];
- ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
- mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 );
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
- "version = [%d:%d], msglen = %d",
- ssl->in_msgtype,
- major_ver, minor_ver, ssl->in_msglen ) );
-
- /* Check record type */
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* Silently ignore invalid DTLS records as recommended by RFC 6347
- * Section 4.1.2.7 */
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
-
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- /* Check version */
- if( major_ver != ssl->major_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- if( minor_ver > ssl->conf->max_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- /* Check length against the size of our buffer */
- if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN
- - (size_t)( ssl->in_msg - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- /*
- * DTLS-related tests.
- * Check epoch before checking length constraint because
- * the latter varies with the epoch. E.g., if a ChangeCipherSpec
- * message gets duplicated before the corresponding Finished message,
- * the second ChangeCipherSpec should be discarded because it belongs
- * to an old epoch, but not because its length is shorter than
- * the minimum record length for packets using the new record transform.
- * Note that these two kinds of failures are handled differently,
- * as an unexpected record is silently skipped but an invalid
- * record leads to the entire datagram being dropped.
- */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
-
- /* Check epoch (and sequence number) with DTLS */
- if( rec_epoch != ssl->in_epoch )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
- "expected %d, received %d",
- ssl->in_epoch, rec_epoch ) );
-
-#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
- /*
- * Check for an epoch 0 ClientHello. We can't use in_msg here to
- * access the first byte of record content (handshake type), as we
- * have an active transform (possibly iv_len != 0), so use the
- * fact that the record header len is 13 instead.
- */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
- rec_epoch == 0 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_left > 13 &&
- ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
- "from the same port" ) );
- return( ssl_handle_possible_reconnect( ssl ) );
- }
- else
-#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
- {
- /* Consider buffering the record. */
- if( rec_epoch == (unsigned int) ssl->in_epoch + 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) );
- return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
- }
-
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
- }
-
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- /* Replay detection only works for the current epoch */
- if( rec_epoch == ssl->in_epoch &&
- mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
-#endif
-
- /* Drop unexpected ApplicationData records,
- * except at the beginning of renegotiations */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
- ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->state == MBEDTLS_SSL_SERVER_HELLO )
-#endif
- )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-
- /* Check length against bounds of the current transform and version */
- if( ssl->transform_in == NULL )
- {
- if( ssl->in_msglen < 1 ||
- ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- }
- else
- {
- if( ssl->in_msglen < ssl->transform_in->minlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
- ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * TLS encrypted messages can have up to 256 bytes of padding
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
- ssl->in_msglen > ssl->transform_in->minlen +
- MBEDTLS_SSL_IN_CONTENT_LEN + 256 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-#endif
- }
-
- return( 0 );
-}
-
-/*
- * If applicable, decrypt (and decompress) record content
- */
-static int ssl_prepare_record_content( mbedtls_ssl_context *ssl )
-{
- int ret, done = 0;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
- ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen );
-
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_read != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
-
- ret = mbedtls_ssl_hw_record_read( ssl );
- if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
-
- if( ret == 0 )
- done = 1;
- }
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- if( !done && ssl->transform_in != NULL )
- {
- if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
- return( ret );
- }
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
- ssl->in_msg, ssl->in_msglen );
-
- if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- }
-
-#if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->transform_in != NULL &&
- ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
- {
- if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
- return( ret );
- }
- }
-#endif /* MBEDTLS_ZLIB_SUPPORT */
-
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- mbedtls_ssl_dtls_replay_update( ssl );
- }
-#endif
-
- return( 0 );
-}
-
-static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
-
-/*
- * Read a record.
- *
- * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
- * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
- *
- */
-
-/* Helper functions for mbedtls_ssl_read_record(). */
-static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
-static int ssl_get_next_record( mbedtls_ssl_context *ssl );
-static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
-
-int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
- unsigned update_hs_digest )
-{
- int ret;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
-
- if( ssl->keep_current_message == 0 )
- {
- do {
-
- ret = ssl_consume_current_message( ssl );
- if( ret != 0 )
- return( ret );
-
- if( ssl_record_is_in_progress( ssl ) == 0 )
- {
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- int have_buffered = 0;
-
- /* We only check for buffered messages if the
- * current datagram is fully consumed. */
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl_next_record_is_in_datagram( ssl ) == 0 )
- {
- if( ssl_load_buffered_message( ssl ) == 0 )
- have_buffered = 1;
- }
-
- if( have_buffered == 0 )
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- {
- ret = ssl_get_next_record( ssl );
- if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
- continue;
-
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
- return( ret );
- }
- }
- }
-
- ret = mbedtls_ssl_handle_message_type( ssl );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
- {
- /* Buffer future message */
- ret = ssl_buffer_message( ssl );
- if( ret != 0 )
- return( ret );
-
- ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ||
- MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret );
-
- if( 0 != ret )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
- return( ret );
- }
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- update_hs_digest == 1 )
- {
- mbedtls_ssl_update_handshake_status( ssl );
- }
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
- ssl->keep_current_message = 0;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
-{
- if( ssl->in_left > ssl->next_record_offset )
- return( 1 );
-
- return( 0 );
-}
-
-static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- mbedtls_ssl_hs_buffer * hs_buf;
- int ret = 0;
-
- if( hs == NULL )
- return( -1 );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) );
-
- if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
- ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
- {
- /* Check if we have seen a ChangeCipherSpec before.
- * If yes, synthesize a CCS record. */
- if( !hs->buffering.seen_ccs )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) );
- ret = -1;
- goto exit;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) );
- ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
- ssl->in_msglen = 1;
- ssl->in_msg[0] = 1;
-
- /* As long as they are equal, the exact value doesn't matter. */
- ssl->in_left = 0;
- ssl->next_record_offset = 0;
-
- hs->buffering.seen_ccs = 0;
- goto exit;
- }
-
-#if defined(MBEDTLS_DEBUG_C)
- /* Debug only */
- {
- unsigned offset;
- for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
- {
- hs_buf = &hs->buffering.hs[offset];
- if( hs_buf->is_valid == 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.",
- hs->in_msg_seq + offset,
- hs_buf->is_complete ? "fully" : "partially" ) );
- }
- }
- }
-#endif /* MBEDTLS_DEBUG_C */
-
- /* Check if we have buffered and/or fully reassembled the
- * next handshake message. */
- hs_buf = &hs->buffering.hs[0];
- if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) )
- {
- /* Synthesize a record containing the buffered HS message. */
- size_t msg_len = ( hs_buf->data[1] << 16 ) |
- ( hs_buf->data[2] << 8 ) |
- hs_buf->data[3];
-
- /* Double-check that we haven't accidentally buffered
- * a message that doesn't fit into the input buffer. */
- if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)",
- hs_buf->data, msg_len + 12 );
-
- ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->in_hslen = msg_len + 12;
- ssl->in_msglen = msg_len + 12;
- memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen );
-
- ret = 0;
- goto exit;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered",
- hs->in_msg_seq ) );
- }
-
- ret = -1;
-
-exit:
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) );
- return( ret );
-}
-
-static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
- size_t desired )
-{
- int offset;
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available",
- (unsigned) desired ) );
-
- /* Get rid of future records epoch first, if such exist. */
- ssl_free_buffered_record( ssl );
-
- /* Check if we have enough space available now. */
- if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
- hs->buffering.total_bytes_buffered ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) );
- return( 0 );
- }
-
- /* We don't have enough space to buffer the next expected handshake
- * message. Remove buffers used for future messages to gain space,
- * starting with the most distant one. */
- for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
- offset >= 0; offset-- )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message",
- offset ) );
-
- ssl_buffering_free_slot( ssl, (uint8_t) offset );
-
- /* Check if we have enough space available now. */
- if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
- hs->buffering.total_bytes_buffered ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) );
- return( 0 );
- }
- }
-
- return( -1 );
-}
-
-static int ssl_buffer_message( mbedtls_ssl_context *ssl )
-{
- int ret = 0;
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
-
- if( hs == NULL )
- return( 0 );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) );
-
- switch( ssl->in_msgtype )
- {
- case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) );
-
- hs->buffering.seen_ccs = 1;
- break;
-
- case MBEDTLS_SSL_MSG_HANDSHAKE:
- {
- unsigned recv_msg_seq_offset;
- unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
- mbedtls_ssl_hs_buffer *hs_buf;
- size_t msg_len = ssl->in_hslen - 12;
-
- /* We should never receive an old handshake
- * message - double-check nonetheless. */
- if( recv_msg_seq < ssl->handshake->in_msg_seq )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
- if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS )
- {
- /* Silently ignore -- message too far in the future */
- MBEDTLS_SSL_DEBUG_MSG( 2,
- ( "Ignore future HS message with sequence number %u, "
- "buffering window %u - %u",
- recv_msg_seq, ssl->handshake->in_msg_seq,
- ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) );
-
- goto exit;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ",
- recv_msg_seq, recv_msg_seq_offset ) );
-
- hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ];
-
- /* Check if the buffering for this seq nr has already commenced. */
- if( !hs_buf->is_valid )
- {
- size_t reassembly_buf_sz;
-
- hs_buf->is_fragmented =
- ( ssl_hs_is_proper_fragment( ssl ) == 1 );
-
- /* We copy the message back into the input buffer
- * after reassembly, so check that it's not too large.
- * This is an implementation-specific limitation
- * and not one from the standard, hence it is not
- * checked in ssl_check_hs_header(). */
- if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- /* Ignore message */
- goto exit;
- }
-
- /* Check if we have enough space to buffer the message. */
- if( hs->buffering.total_bytes_buffered >
- MBEDTLS_SSL_DTLS_MAX_BUFFERING )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
- hs_buf->is_fragmented );
-
- if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
- hs->buffering.total_bytes_buffered ) )
- {
- if( recv_msg_seq_offset > 0 )
- {
- /* If we can't buffer a future message because
- * of space limitations -- ignore. */
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
- (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
- (unsigned) hs->buffering.total_bytes_buffered ) );
- goto exit;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n",
- (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
- (unsigned) hs->buffering.total_bytes_buffered ) );
- }
-
- if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n",
- (unsigned) msg_len,
- (unsigned) reassembly_buf_sz,
- MBEDTLS_SSL_DTLS_MAX_BUFFERING,
- (unsigned) hs->buffering.total_bytes_buffered ) );
- ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
- goto exit;
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d",
- msg_len ) );
-
- hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
- if( hs_buf->data == NULL )
- {
- ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
- goto exit;
- }
- hs_buf->data_len = reassembly_buf_sz;
-
- /* Prepare final header: copy msg_type, length and message_seq,
- * then add standardised fragment_offset and fragment_length */
- memcpy( hs_buf->data, ssl->in_msg, 6 );
- memset( hs_buf->data + 6, 0, 3 );
- memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
-
- hs_buf->is_valid = 1;
-
- hs->buffering.total_bytes_buffered += reassembly_buf_sz;
- }
- else
- {
- /* Make sure msg_type and length are consistent */
- if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) );
- /* Ignore */
- goto exit;
- }
- }
-
- if( !hs_buf->is_complete )
- {
- size_t frag_len, frag_off;
- unsigned char * const msg = hs_buf->data + 12;
-
- /*
- * Check and copy current fragment
- */
-
- /* Validation of header fields already done in
- * mbedtls_ssl_prepare_handshake_record(). */
- frag_off = ssl_get_hs_frag_off( ssl );
- frag_len = ssl_get_hs_frag_len( ssl );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d",
- frag_off, frag_len ) );
- memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
-
- if( hs_buf->is_fragmented )
- {
- unsigned char * const bitmask = msg + msg_len;
- ssl_bitmask_set( bitmask, frag_off, frag_len );
- hs_buf->is_complete = ( ssl_bitmask_check( bitmask,
- msg_len ) == 0 );
- }
- else
- {
- hs_buf->is_complete = 1;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete",
- hs_buf->is_complete ? "" : "not yet " ) );
- }
-
- break;
- }
-
- default:
- /* We don't buffer other types of messages. */
- break;
- }
-
-exit:
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) );
- return( ret );
-}
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
-{
- /*
- * Consume last content-layer message and potentially
- * update in_msglen which keeps track of the contents'
- * consumption state.
- *
- * (1) Handshake messages:
- * Remove last handshake message, move content
- * and adapt in_msglen.
- *
- * (2) Alert messages:
- * Consume whole record content, in_msglen = 0.
- *
- * (3) Change cipher spec:
- * Consume whole record content, in_msglen = 0.
- *
- * (4) Application data:
- * Don't do anything - the record layer provides
- * the application data as a stream transport
- * and consumes through mbedtls_ssl_read only.
- *
- */
-
- /* Case (1): Handshake messages */
- if( ssl->in_hslen != 0 )
- {
- /* Hard assertion to be sure that no application data
- * is in flight, as corrupting ssl->in_msglen during
- * ssl->in_offt != NULL is fatal. */
- if( ssl->in_offt != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- /*
- * Get next Handshake message in the current record
- */
-
- /* Notes:
- * (1) in_hslen is not necessarily the size of the
- * current handshake content: If DTLS handshake
- * fragmentation is used, that's the fragment
- * size instead. Using the total handshake message
- * size here is faulty and should be changed at
- * some point.
- * (2) While it doesn't seem to cause problems, one
- * has to be very careful not to assume that in_hslen
- * is always <= in_msglen in a sensible communication.
- * Again, it's wrong for DTLS handshake fragmentation.
- * The following check is therefore mandatory, and
- * should not be treated as a silently corrected assertion.
- * Additionally, ssl->in_hslen might be arbitrarily out of
- * bounds after handling a DTLS message with an unexpected
- * sequence number, see mbedtls_ssl_prepare_handshake_record.
- */
- if( ssl->in_hslen < ssl->in_msglen )
- {
- ssl->in_msglen -= ssl->in_hslen;
- memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
- ssl->in_msglen );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
- ssl->in_msg, ssl->in_msglen );
- }
- else
- {
- ssl->in_msglen = 0;
- }
-
- ssl->in_hslen = 0;
- }
- /* Case (4): Application data */
- else if( ssl->in_offt != NULL )
- {
- return( 0 );
- }
- /* Everything else (CCS & Alerts) */
- else
- {
- ssl->in_msglen = 0;
- }
-
- return( 0 );
-}
-
-static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
-{
- if( ssl->in_msglen > 0 )
- return( 1 );
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-
-static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- if( hs == NULL )
- return;
-
- if( hs->buffering.future_record.data != NULL )
- {
- hs->buffering.total_bytes_buffered -=
- hs->buffering.future_record.len;
-
- mbedtls_free( hs->buffering.future_record.data );
- hs->buffering.future_record.data = NULL;
- }
-}
-
-static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- unsigned char * rec;
- size_t rec_len;
- unsigned rec_epoch;
-
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( 0 );
-
- if( hs == NULL )
- return( 0 );
-
- rec = hs->buffering.future_record.data;
- rec_len = hs->buffering.future_record.len;
- rec_epoch = hs->buffering.future_record.epoch;
-
- if( rec == NULL )
- return( 0 );
-
- /* Only consider loading future records if the
- * input buffer is empty. */
- if( ssl_next_record_is_in_datagram( ssl ) == 1 )
- return( 0 );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) );
-
- if( rec_epoch != ssl->in_epoch )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) );
- goto exit;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
-
- /* Double-check that the record is not too large */
- if( rec_len > MBEDTLS_SSL_IN_BUFFER_LEN -
- (size_t)( ssl->in_hdr - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- memcpy( ssl->in_hdr, rec, rec_len );
- ssl->in_left = rec_len;
- ssl->next_record_offset = 0;
-
- ssl_free_buffered_record( ssl );
-
-exit:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) );
- return( 0 );
-}
-
-static int ssl_buffer_future_record( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- size_t const rec_hdr_len = 13;
- size_t const total_buf_sz = rec_hdr_len + ssl->in_msglen;
-
- /* Don't buffer future records outside handshakes. */
- if( hs == NULL )
- return( 0 );
-
- /* Only buffer handshake records (we are only interested
- * in Finished messages). */
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- return( 0 );
-
- /* Don't buffer more than one future epoch record. */
- if( hs->buffering.future_record.data != NULL )
- return( 0 );
-
- /* Don't buffer record if there's not enough buffering space remaining. */
- if( total_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
- hs->buffering.total_bytes_buffered ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
- (unsigned) total_buf_sz, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
- (unsigned) hs->buffering.total_bytes_buffered ) );
- return( 0 );
- }
-
- /* Buffer record */
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u",
- ssl->in_epoch + 1 ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", ssl->in_hdr,
- rec_hdr_len + ssl->in_msglen );
-
- /* ssl_parse_record_header() only considers records
- * of the next epoch as candidates for buffering. */
- hs->buffering.future_record.epoch = ssl->in_epoch + 1;
- hs->buffering.future_record.len = total_buf_sz;
-
- hs->buffering.future_record.data =
- mbedtls_calloc( 1, hs->buffering.future_record.len );
- if( hs->buffering.future_record.data == NULL )
- {
- /* If we run out of RAM trying to buffer a
- * record from the next epoch, just ignore. */
- return( 0 );
- }
-
- memcpy( hs->buffering.future_record.data, ssl->in_hdr, total_buf_sz );
-
- hs->buffering.total_bytes_buffered += total_buf_sz;
- return( 0 );
-}
-
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-static int ssl_get_next_record( mbedtls_ssl_context *ssl )
-{
- int ret;
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* We might have buffered a future record; if so,
- * and if the epoch matches now, load it.
- * On success, this call will set ssl->in_left to
- * the length of the buffered record, so that
- * the calls to ssl_fetch_input() below will
- * essentially be no-ops. */
- ret = ssl_load_buffered_record( ssl );
- if( ret != 0 )
- return( ret );
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
-
- if( ( ret = ssl_parse_record_header( ssl ) ) != 0 )
- {
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
- {
- if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
- {
- ret = ssl_buffer_future_record( ssl );
- if( ret != 0 )
- return( ret );
-
- /* Fall through to handling of unexpected records */
- ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
- }
-
- if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
- {
- /* Skip unexpected record (but not whole datagram) */
- ssl->next_record_offset = ssl->in_msglen
- + mbedtls_ssl_hdr_len( ssl );
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
- "(header)" ) );
- }
- else
- {
- /* Skip invalid record and the rest of the datagram */
- ssl->next_record_offset = 0;
- ssl->in_left = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
- "(header)" ) );
- }
-
- /* Get next record */
- return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
- }
-#endif
- return( ret );
- }
-
- /*
- * Read and optionally decrypt the message contents
- */
- if( ( ret = mbedtls_ssl_fetch_input( ssl,
- mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
-
- /* Done reading this record, get ready for the next one */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl );
- if( ssl->next_record_offset < ssl->in_left )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
- }
- }
- else
-#endif
- ssl->in_left = 0;
-
- if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 )
- {
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Silently discard invalid records */
- if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD ||
- ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- /* Except when waiting for Finished as a bad mac here
- * probably means something went wrong in the handshake
- * (eg wrong psk used, mitm downgrade attempt, etc.) */
- if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
- ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
- {
-#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
- if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
- }
-#endif
- return( ret );
- }
-
-#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
- if( ssl->conf->badmac_limit != 0 &&
- ++ssl->badmac_seen >= ssl->conf->badmac_limit )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
-#endif
-
- /* As above, invalid records cause
- * dismissal of the whole datagram. */
-
- ssl->next_record_offset = 0;
- ssl->in_left = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
- return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
- }
-
- return( ret );
- }
- else
-#endif
- {
- /* Error out (and send alert) on invalid records */
-#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
- if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
- }
-#endif
- return( ret );
- }
- }
-
- return( 0 );
-}
-
-int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
-{
- int ret;
-
- /*
- * Handle particular types of records
- */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
- {
- return( ret );
- }
- }
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
- {
- if( ssl->in_msglen != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d",
- ssl->in_msglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- if( ssl->in_msg[0] != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x",
- ssl->in_msg[0] ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
- ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
- {
- if( ssl->handshake == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) );
- return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
- }
-#endif
- }
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
- {
- if( ssl->in_msglen != 2 )
- {
- /* Note: Standard allows for more than one 2 byte alert
- to be packed in a single message, but Mbed TLS doesn't
- currently support this. */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d",
- ssl->in_msglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
- ssl->in_msg[0], ssl->in_msg[1] ) );
-
- /*
- * Ignore non-fatal alerts, except close_notify and no_renegotiation
- */
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
- ssl->in_msg[1] ) );
- return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
- }
-
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
- return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
- }
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) );
- /* Will be handled when trying to parse ServerHello */
- return( 0 );
- }
-#endif
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
- ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
- /* Will be handled in mbedtls_ssl_parse_certificate() */
- return( 0 );
- }
-#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
-
- /* Silently ignore: fetch new message */
- return MBEDTLS_ERR_SSL_NON_FATAL;
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL &&
- ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- ssl_handshake_wrapup_free_hs_transform( ssl );
- }
-#endif
-
- return( 0 );
-}
-
-int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static void ssl_clear_peer_cert( mbedtls_ssl_session *session )
{
- int ret;
-
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 )
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if( session->peer_cert != NULL )
{
- return( ret );
+ mbedtls_x509_crt_free( session->peer_cert );
+ mbedtls_free( session->peer_cert );
+ session->peer_cert = NULL;
}
-
- return( 0 );
-}
-
-int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
- unsigned char level,
- unsigned char message )
-{
- int ret;
-
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
-
- ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
- ssl->out_msglen = 2;
- ssl->out_msg[0] = level;
- ssl->out_msg[1] = message;
-
- if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( session->peer_cert_digest != NULL )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
+ /* Zeroization is not necessary. */
+ mbedtls_free( session->peer_cert_digest );
+ session->peer_cert_digest = NULL;
+ session->peer_cert_digest_type = MBEDTLS_MD_NONE;
+ session->peer_cert_digest_len = 0;
}
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
-
- return( 0 );
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
/*
* Handshake functions
*/
-#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/* No certificate support -> dummy functions */
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
{
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++;
@@ -5578,14 +2186,12 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
ssl->state++;
@@ -5596,7 +2202,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else
+#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/* Some certificate support -> implement write and parse */
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
@@ -5604,14 +2210,12 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
size_t i, n;
const mbedtls_x509_crt *crt;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++;
@@ -5677,22 +2281,23 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
n = crt->raw.len;
if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d",
- i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %" MBEDTLS_PRINTF_SIZET
+ " > %" MBEDTLS_PRINTF_SIZET,
+ i + 3 + n, (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE );
}
- ssl->out_msg[i ] = (unsigned char)( n >> 16 );
- ssl->out_msg[i + 1] = (unsigned char)( n >> 8 );
- ssl->out_msg[i + 2] = (unsigned char)( n );
+ ssl->out_msg[i ] = MBEDTLS_BYTE_2( n );
+ ssl->out_msg[i + 1] = MBEDTLS_BYTE_1( n );
+ ssl->out_msg[i + 2] = MBEDTLS_BYTE_0( n );
i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
i += n; crt = crt->next;
}
- ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 );
- ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 );
- ssl->out_msg[6] = (unsigned char)( ( i - 7 ) );
+ ssl->out_msg[4] = MBEDTLS_BYTE_2( i - 7 );
+ ssl->out_msg[5] = MBEDTLS_BYTE_1( i - 7 );
+ ssl->out_msg[6] = MBEDTLS_BYTE_0( i - 7 );
ssl->out_msglen = i;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@@ -5715,63 +2320,68 @@ write_msg:
return( ret );
}
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
+ unsigned char *crt_buf,
+ size_t crt_buf_len )
+{
+ mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
+
+ if( peer_crt == NULL )
+ return( -1 );
+
+ if( peer_crt->raw.len != crt_buf_len )
+ return( -1 );
+
+ return( memcmp( peer_crt->raw.p, crt_buf, peer_crt->raw.len ) );
+}
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
+ unsigned char *crt_buf,
+ size_t crt_buf_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char const * const peer_cert_digest =
+ ssl->session->peer_cert_digest;
+ mbedtls_md_type_t const peer_cert_digest_type =
+ ssl->session->peer_cert_digest_type;
+ mbedtls_md_info_t const * const digest_info =
+ mbedtls_md_info_from_type( peer_cert_digest_type );
+ unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN];
+ size_t digest_len;
+
+ if( peer_cert_digest == NULL || digest_info == NULL )
+ return( -1 );
+
+ digest_len = mbedtls_md_get_size( digest_info );
+ if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN )
+ return( -1 );
+
+ ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest );
+ if( ret != 0 )
+ return( -1 );
+
+ return( memcmp( tmp_digest, peer_cert_digest, digest_len ) );
+}
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
/*
* Once the certificate message is read, parse it into a cert chain and
* perform basic checks, but leave actual verification to the caller
*/
-static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl )
+static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *chain )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+ int crt_cnt=0;
+#endif
size_t i, n;
uint8_t alert;
-#if defined(MBEDTLS_SSL_SRV_C)
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- /*
- * Check if the client sent an empty certificate
- */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( ssl->in_msglen == 2 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
- ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
-
- /* The client was asked for a certificate but didn't send
- one. The client should know what's going on, so we
- don't send an alert. */
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
- return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
- memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
-
- /* The client was asked for a certificate but didn't send
- one. The client should know what's going on, so we
- don't send an alert. */
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
- return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
-#endif /* MBEDTLS_SSL_SRV_C */
-
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
@@ -5805,43 +2415,32 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
- /* In case we tried to reuse a session but it failed */
- if( ssl->session_negotiate->peer_cert != NULL )
- {
- mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert );
- mbedtls_free( ssl->session_negotiate->peer_cert );
- }
-
- if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1,
- sizeof( mbedtls_x509_crt ) ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
- sizeof( mbedtls_x509_crt ) ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
-
- mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert );
-
+ /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
i += 3;
+ /* Iterate through and parse the CRTs in the provided chain. */
while( i < ssl->in_hslen )
{
+ /* Check that there's room for the next CRT's length fields. */
if ( i + 3 > ssl->in_hslen ) {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+ /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
+ * anything beyond 2**16 ~ 64K. */
if( ssl->in_msg[i] != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+ /* Read length of the next CRT in the chain. */
n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
| (unsigned int) ssl->in_msg[i + 2];
i += 3;
@@ -5849,161 +2448,207 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl )
if( n < 128 || i + n > ssl->in_hslen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
- ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert,
- ssl->in_msg + i, n );
+ /* Check if we're handling the first CRT in the chain. */
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+ if( crt_cnt++ == 0 &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+ {
+ /* During client-side renegotiation, check that the server's
+ * end-CRTs hasn't changed compared to the initial handshake,
+ * mitigating the triple handshake attack. On success, reuse
+ * the original end-CRT instead of parsing it again. */
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Check that peer CRT hasn't changed during renegotiation" ) );
+ if( ssl_check_peer_crt_unchanged( ssl,
+ &ssl->in_msg[i],
+ n ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+ }
+
+ /* Now we can safely free the original chain. */
+ ssl_clear_peer_cert( ssl->session );
+ }
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
+ /* Parse the next certificate in the chain. */
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ ret = mbedtls_x509_crt_parse_der( chain, ssl->in_msg + i, n );
+#else
+ /* If we don't need to store the CRT chain permanently, parse
+ * it in-place from the input buffer instead of making a copy. */
+ ret = mbedtls_x509_crt_parse_der_nocopy( chain, ssl->in_msg + i, n );
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
switch( ret )
{
- case 0: /*ok*/
- case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
- /* Ignore certificate with an unknown algorithm: maybe a
- prior certificate was already trusted. */
- break;
+ case 0: /*ok*/
+ case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
+ /* Ignore certificate with an unknown algorithm: maybe a
+ prior certificate was already trusted. */
+ break;
- case MBEDTLS_ERR_X509_ALLOC_FAILED:
- alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
- goto crt_parse_der_failed;
+ case MBEDTLS_ERR_X509_ALLOC_FAILED:
+ alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
+ goto crt_parse_der_failed;
- case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- goto crt_parse_der_failed;
+ case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ goto crt_parse_der_failed;
- default:
- alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
- crt_parse_der_failed:
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
- MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
- return( ret );
+ default:
+ alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+ crt_parse_der_failed:
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
+ MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
+ return( ret );
}
i += n;
}
- MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert );
+ MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", chain );
+ return( 0 );
+}
+#if defined(MBEDTLS_SSL_SRV_C)
+static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl )
+{
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+ return( -1 );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
/*
- * On client, make sure the server cert doesn't change during renego to
- * avoid "triple handshake" attack: https://secure-resumption.com/
+ * Check if the client sent an empty certificate
*/
-#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{
- if( ssl->session->peer_cert == NULL )
+ if( ssl->in_msglen == 2 &&
+ ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
+ ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+ ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
+ return( 0 );
}
- if( ssl->session->peer_cert->raw.len !=
- ssl->session_negotiate->peer_cert->raw.len ||
- memcmp( ssl->session->peer_cert->raw.p,
- ssl->session_negotiate->peer_cert->raw.p,
- ssl->session->peer_cert->raw.len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
+ return( -1 );
}
-#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
- return( 0 );
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
+ ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
+ memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
+ return( 0 );
+ }
+
+ return( -1 );
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+ MBEDTLS_SSL_PROTO_TLS1_2 */
}
+#endif /* MBEDTLS_SSL_SRV_C */
-int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+/* Check if a certificate message is expected.
+ * Return either
+ * - SSL_CERTIFICATE_EXPECTED, or
+ * - SSL_CERTIFICATE_SKIP
+ * indicating whether a Certificate message is expected or not.
+ */
+#define SSL_CERTIFICATE_EXPECTED 0
+#define SSL_CERTIFICATE_SKIP 1
+static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
+ int authmode )
{
- int ret;
- const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
-#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
- ? ssl->handshake->sni_authmode
- : ssl->conf->authmode;
-#else
- const int authmode = ssl->conf->authmode;
-#endif
- void *rs_ctx = NULL;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
-
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- ssl->state++;
- return( 0 );
- }
+ if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
+ return( SSL_CERTIFICATE_SKIP );
#if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- ssl->state++;
- return( 0 );
+ if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+ return( SSL_CERTIFICATE_SKIP );
+
+ if( authmode == MBEDTLS_SSL_VERIFY_NONE )
+ {
+ ssl->session_negotiate->verify_result =
+ MBEDTLS_X509_BADCERT_SKIP_VERIFY;
+ return( SSL_CERTIFICATE_SKIP );
+ }
}
+#else
+ ((void) authmode);
+#endif /* MBEDTLS_SSL_SRV_C */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- authmode == MBEDTLS_SSL_VERIFY_NONE )
- {
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+ return( SSL_CERTIFICATE_EXPECTED );
+}
- ssl->state++;
+static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
+ int authmode,
+ mbedtls_x509_crt *chain,
+ void *rs_ctx )
+{
+ int ret = 0;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
+ int have_ca_chain = 0;
+
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
+ void *p_vrfy;
+
+ if( authmode == MBEDTLS_SSL_VERIFY_NONE )
return( 0 );
- }
-#endif
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- if( ssl->handshake->ecrs_enabled &&
- ssl->handshake->ecrs_state == ssl_ecrs_crt_verify )
+ if( ssl->f_vrfy != NULL )
{
- goto crt_verify;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use context-specific verification callback" ) );
+ f_vrfy = ssl->f_vrfy;
+ p_vrfy = ssl->p_vrfy;
}
-#endif
-
- if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+ else
{
- /* mbedtls_ssl_read_record may have sent an alert already. We
- let it decide whether to alert. */
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use configuration-specific verification callback" ) );
+ f_vrfy = ssl->conf->f_vrfy;
+ p_vrfy = ssl->conf->p_vrfy;
}
- if( ( ret = ssl_parse_certificate_chain( ssl ) ) != 0 )
- {
-#if defined(MBEDTLS_SSL_SRV_C)
- if( ret == MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE &&
- authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
- {
- ret = 0;
- }
-#endif
-
- ssl->state++;
- return( ret );
+ /*
+ * Main check: verify certificate
+ */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ if( ssl->conf->f_ca_cb != NULL )
+ {
+ ((void) rs_ctx);
+ have_ca_chain = 1;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "use CA callback for X.509 CRT verification" ) );
+ ret = mbedtls_x509_crt_verify_with_ca_cb(
+ chain,
+ ssl->conf->f_ca_cb,
+ ssl->conf->p_ca_cb,
+ ssl->conf->cert_profile,
+ ssl->hostname,
+ &ssl->session_negotiate->verify_result,
+ f_vrfy, p_vrfy );
}
-
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- if( ssl->handshake->ecrs_enabled)
- ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
-
-crt_verify:
- if( ssl->handshake->ecrs_enabled)
- rs_ctx = &ssl->handshake->ecrs_ctx;
-#endif
-
- if( authmode != MBEDTLS_SSL_VERIFY_NONE )
+ else
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
{
mbedtls_x509_crt *ca_chain;
mbedtls_x509_crl *ca_crl;
@@ -6021,232 +2666,327 @@ crt_verify:
ca_crl = ssl->conf->ca_crl;
}
- /*
- * Main check: verify certificate
- */
+ if( ca_chain != NULL )
+ have_ca_chain = 1;
+
ret = mbedtls_x509_crt_verify_restartable(
- ssl->session_negotiate->peer_cert,
- ca_chain, ca_crl,
- ssl->conf->cert_profile,
- ssl->hostname,
- &ssl->session_negotiate->verify_result,
- ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx );
+ chain,
+ ca_chain, ca_crl,
+ ssl->conf->cert_profile,
+ ssl->hostname,
+ &ssl->session_negotiate->verify_result,
+ f_vrfy, p_vrfy, rs_ctx );
+ }
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
- }
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
+ }
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
- return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+ return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
#endif
- /*
- * Secondary checks: always done, but change 'ret' only if it was 0
- */
+ /*
+ * Secondary checks: always done, but change 'ret' only if it was 0
+ */
#if defined(MBEDTLS_ECP_C)
- {
- const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk;
-
- /* If certificate uses an EC key, make sure the curve is OK */
- if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
- mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
- {
- ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
- if( ret == 0 )
- ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
- }
- }
-#endif /* MBEDTLS_ECP_C */
+ {
+ const mbedtls_pk_context *pk = &chain->pk;
- if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
- ciphersuite_info,
- ! ssl->conf->endpoint,
- &ssl->session_negotiate->verify_result ) != 0 )
+ /* If certificate uses an EC key, make sure the curve is OK */
+ if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
+ mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
+ ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
if( ret == 0 )
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
}
+ }
+#endif /* MBEDTLS_ECP_C */
- /* mbedtls_x509_crt_verify_with_profile is supposed to report a
- * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
- * with details encoded in the verification flags. All other kinds
- * of error codes, including those from the user provided f_vrfy
- * functions, are treated as fatal and lead to a failure of
- * ssl_parse_certificate even if verification was optional. */
- if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
- ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
- ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
- {
- ret = 0;
- }
+ if( mbedtls_ssl_check_cert_usage( chain,
+ ciphersuite_info,
+ ! ssl->conf->endpoint,
+ &ssl->session_negotiate->verify_result ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
+ if( ret == 0 )
+ ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
+ }
- if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
- ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
- }
+ /* mbedtls_x509_crt_verify_with_profile is supposed to report a
+ * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
+ * with details encoded in the verification flags. All other kinds
+ * of error codes, including those from the user provided f_vrfy
+ * functions, are treated as fatal and lead to a failure of
+ * ssl_parse_certificate even if verification was optional. */
+ if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
+ ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
+ ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
+ {
+ ret = 0;
+ }
- if( ret != 0 )
- {
- uint8_t alert;
-
- /* The certificate may have been rejected for several reasons.
- Pick one and send the corresponding alert. Which alert to send
- may be a subject of debate in some cases. */
- if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
- alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
- alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
- alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
- alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
- alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
- else
- alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- alert );
- }
+ if( have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
+ ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
+ }
-#if defined(MBEDTLS_DEBUG_C)
- if( ssl->session_negotiate->verify_result != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x",
- ssl->session_negotiate->verify_result ) );
- }
+ if( ret != 0 )
+ {
+ uint8_t alert;
+
+ /* The certificate may have been rejected for several reasons.
+ Pick one and send the corresponding alert. Which alert to send
+ may be a subject of debate in some cases. */
+ if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
+ alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
+ alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
+ alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
+ alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
else
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
- }
-#endif /* MBEDTLS_DEBUG_C */
+ alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ alert );
}
- ssl->state++;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
+#if defined(MBEDTLS_DEBUG_C)
+ if( ssl->session_negotiate->verify_result != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %08x",
+ (unsigned int) ssl->session_negotiate->verify_result ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
+ }
+#endif /* MBEDTLS_DEBUG_C */
return( ret );
}
-#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl,
+ unsigned char *start, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* Remember digest of the peer's end-CRT. */
+ ssl->session_negotiate->peer_cert_digest =
+ mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN );
+ if( ssl->session_negotiate->peer_cert_digest == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+ MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ) );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
+ ret = mbedtls_md( mbedtls_md_info_from_type(
+ MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ),
+ start, len,
+ ssl->session_negotiate->peer_cert_digest );
- ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
- ssl->out_msglen = 1;
- ssl->out_msg[0] = 1;
+ ssl->session_negotiate->peer_cert_digest_type =
+ MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
+ ssl->session_negotiate->peer_cert_digest_len =
+ MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
- ssl->state++;
+ return( ret );
+}
- if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl,
+ unsigned char *start, size_t len )
+{
+ unsigned char *end = start + len;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* Make a copy of the peer's raw public key. */
+ mbedtls_pk_init( &ssl->handshake->peer_pubkey );
+ ret = mbedtls_pk_parse_subpubkey( &start, end,
+ &ssl->handshake->peer_pubkey );
+ if( ret != 0 )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
- return( ret );
+ /* We should have parsed the public key before. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
-
return( 0 );
}
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = 0;
+ int crt_expected;
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
+ ? ssl->handshake->sni_authmode
+ : ssl->conf->authmode;
+#else
+ const int authmode = ssl->conf->authmode;
+#endif
+ void *rs_ctx = NULL;
+ mbedtls_x509_crt *chain = NULL;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
+
+ crt_expected = ssl_parse_certificate_coordinate( ssl, authmode );
+ if( crt_expected == SSL_CERTIFICATE_SKIP )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+ goto exit;
+ }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ if( ssl->handshake->ecrs_enabled &&
+ ssl->handshake->ecrs_state == ssl_ecrs_crt_verify )
+ {
+ chain = ssl->handshake->ecrs_peer_cert;
+ ssl->handshake->ecrs_peer_cert = NULL;
+ goto crt_verify;
+ }
+#endif
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{
+ /* mbedtls_ssl_read_record may have sent an alert already. We
+ let it decide whether to alert. */
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
+ goto exit;
}
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+#if defined(MBEDTLS_SSL_SRV_C)
+ if( ssl_srv_check_client_no_crt_notification( ssl ) == 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
+ ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
- /* CCS records are only accepted if they have length 1 and content '1',
- * so we don't need to check this here. */
+ if( authmode != MBEDTLS_SSL_VERIFY_OPTIONAL )
+ ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
- /*
- * Switch to our negotiated transform and session parameters for inbound
- * data.
- */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
- ssl->transform_in = ssl->transform_negotiate;
- ssl->session_in = ssl->session_negotiate;
+ goto exit;
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ /* Clear existing peer CRT structure in case we tried to
+ * reuse a session but it failed, and allocate a new one. */
+ ssl_clear_peer_cert( ssl->session_negotiate );
+
+ chain = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+ if( chain == NULL )
{
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- ssl_dtls_replay_reset( ssl );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed",
+ sizeof( mbedtls_x509_crt ) ) );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ goto exit;
+ }
+ mbedtls_x509_crt_init( chain );
+
+ ret = ssl_parse_certificate_chain( ssl, chain );
+ if( ret != 0 )
+ goto exit;
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ if( ssl->handshake->ecrs_enabled)
+ ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
+
+crt_verify:
+ if( ssl->handshake->ecrs_enabled)
+ rs_ctx = &ssl->handshake->ecrs_ctx;
#endif
- /* Increment epoch */
- if( ++ssl->in_epoch == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
- /* This is highly unlikely to happen for legitimate reasons, so
- treat it as an attack and don't send an alert. */
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
+ ret = ssl_parse_certificate_verify( ssl, authmode,
+ chain, rs_ctx );
+ if( ret != 0 )
+ goto exit;
+
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ {
+ unsigned char *crt_start, *pk_start;
+ size_t crt_len, pk_len;
+
+ /* We parse the CRT chain without copying, so
+ * these pointers point into the input buffer,
+ * and are hence still valid after freeing the
+ * CRT chain. */
+
+ crt_start = chain->raw.p;
+ crt_len = chain->raw.len;
+
+ pk_start = chain->pk_raw.p;
+ pk_len = chain->pk_raw.len;
+
+ /* Free the CRT structures before computing
+ * digest and copying the peer's public key. */
+ mbedtls_x509_crt_free( chain );
+ mbedtls_free( chain );
+ chain = NULL;
+
+ ret = ssl_remember_peer_crt_digest( ssl, crt_start, crt_len );
+ if( ret != 0 )
+ goto exit;
+
+ ret = ssl_remember_peer_pubkey( ssl, pk_start, pk_len );
+ if( ret != 0 )
+ goto exit;
}
- else
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- memset( ssl->in_ctr, 0, 8 );
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /* Pass ownership to session structure. */
+ ssl->session_negotiate->peer_cert = chain;
+ chain = NULL;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- ssl_update_in_pointers( ssl, ssl->transform_negotiate );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_activate != NULL )
+exit:
+
+ if( ret == 0 )
+ ssl->state++;
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
{
- if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
+ ssl->handshake->ecrs_peer_cert = chain;
+ chain = NULL;
}
#endif
- ssl->state++;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
+ if( chain != NULL )
+ {
+ mbedtls_x509_crt_free( chain );
+ mbedtls_free( chain );
+ }
- return( 0 );
+ return( ret );
}
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
@@ -6260,7 +3000,7 @@ void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
ssl->handshake->update_checksum = ssl_update_checksum_sha384;
else
@@ -6286,11 +3026,21 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &ssl->handshake->fin_sha256_psa );
+ psa_hash_setup( &ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
+#else
mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &ssl->handshake->fin_sha384_psa );
+ psa_hash_setup( &ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
+#else
mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
}
@@ -6304,11 +3054,19 @@ static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
+#else
mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
+#else
mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
}
@@ -6327,15 +3085,23 @@ static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
+#else
mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
+#endif
}
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
+#else
mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
+#endif
}
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@@ -6491,13 +3257,44 @@ static void ssl_calc_finished_tls_sha256(
{
int len = 12;
const char *sender;
- mbedtls_sha256_context sha256;
unsigned char padbuf[32];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT;
+ psa_status_t status;
+#else
+ mbedtls_sha256_context sha256;
+#endif
mbedtls_ssl_session *session = ssl->session_negotiate;
if( !session )
session = ssl->session;
+ sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+ ? "client finished"
+ : "server finished";
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ sha256_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha256" ) );
+
+ status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha256_psa, padbuf, sizeof( padbuf ), &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 32 );
+#else
+
mbedtls_sha256_init( &sha256 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) );
@@ -6515,39 +3312,65 @@ static void ssl_calc_finished_tls_sha256(
sha256.state, sizeof( sha256.state ) );
#endif
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
-
mbedtls_sha256_finish_ret( &sha256, padbuf );
+ mbedtls_sha256_free( &sha256 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 32, buf, len );
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_sha256_free( &sha256 );
-
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
}
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static void ssl_calc_finished_tls_sha384(
mbedtls_ssl_context *ssl, unsigned char *buf, int from )
{
int len = 12;
const char *sender;
- mbedtls_sha512_context sha512;
unsigned char padbuf[48];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT;
+ psa_status_t status;
+#else
+ mbedtls_sha512_context sha512;
+#endif
mbedtls_ssl_session *session = ssl->session_negotiate;
if( !session )
session = ssl->session;
+ sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+ ? "client finished"
+ : "server finished";
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ sha384_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha384" ) );
+
+ status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha384_psa, padbuf, sizeof( padbuf ), &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 48 );
+#else
mbedtls_sha512_init( &sha512 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) );
@@ -6564,10 +3387,6 @@ static void ssl_calc_finished_tls_sha384(
MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
sha512.state, sizeof( sha512.state ) );
#endif
-
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
/* mbedtls_sha512_finish_ret's output parameter is declared as a
* 64-byte buffer, but sice we're using SHA-384, we know that the
* output fits in 48 bytes. This is correct C, but GCC 11.1 warns
@@ -6582,21 +3401,22 @@ static void ssl_calc_finished_tls_sha384(
#pragma GCC diagnostic pop
#endif
+ mbedtls_sha512_free( &sha512 );
+#endif
+
ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 48, buf, len );
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_sha512_free( &sha512 );
-
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
}
-#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
+void mbedtls_ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
@@ -6668,7 +3488,7 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
ssl->handshake->flight != NULL )
{
/* Cancel handshake timer */
- ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_set_timer( ssl, 0 );
/* Keep last flight around in case we need to resend it:
* we need the handshake and transform structures for that */
@@ -6676,7 +3496,7 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
}
else
#endif
- ssl_handshake_wrapup_free_hs_transform( ssl );
+ mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
ssl->state++;
@@ -6689,7 +3509,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
- ssl_update_out_pointers( ssl, ssl->transform_negotiate );
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform_negotiate );
ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
@@ -6809,7 +3629,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned int hash_len;
unsigned char buf[SSL_MAX_HASH_LEN];
@@ -6850,7 +3670,7 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
goto exit;
}
- if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
+ if( mbedtls_ct_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
buf, hash_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
@@ -6904,19 +3724,29 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ handshake->fin_sha256_psa = psa_hash_operation_init();
+ psa_hash_setup( &handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
+#else
mbedtls_sha256_init( &handshake->fin_sha256 );
mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ handshake->fin_sha384_psa = psa_hash_operation_init();
+ psa_hash_setup( &handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
+#else
mbedtls_sha512_init( &handshake->fin_sha512 );
mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
handshake->update_checksum = ssl_update_checksum_start;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs );
#endif
@@ -6934,24 +3764,31 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
#endif
#endif
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx );
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_pk_init( &handshake->peer_pubkey );
+#endif
}
-static void ssl_transform_init( mbedtls_ssl_transform *transform )
+void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform )
{
memset( transform, 0, sizeof(mbedtls_ssl_transform) );
mbedtls_cipher_init( &transform->cipher_ctx_enc );
mbedtls_cipher_init( &transform->cipher_ctx_dec );
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
mbedtls_md_init( &transform->md_ctx_enc );
mbedtls_md_init( &transform->md_ctx_dec );
+#endif
}
void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
@@ -6987,6 +3824,12 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
{
ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
}
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ /* If the buffers are too small - reallocate */
+
+ handle_buffer_resizing( ssl, 0, MBEDTLS_SSL_IN_BUFFER_LEN,
+ MBEDTLS_SSL_OUT_BUFFER_LEN );
+#endif
/* All pointers should exist and can be directly freed without issue */
if( ssl->handshake == NULL ||
@@ -7008,7 +3851,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
/* Initialize structures */
mbedtls_ssl_session_init( ssl->session_negotiate );
- ssl_transform_init( ssl->transform_negotiate );
+ mbedtls_ssl_transform_init( ssl->transform_negotiate );
ssl_handshake_params_init( ssl->handshake );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -7021,7 +3864,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
else
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
- ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_set_timer( ssl, 0 );
}
#endif
@@ -7057,78 +3900,6 @@ static int ssl_cookie_check_dummy( void *ctx,
}
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
-/* Once ssl->out_hdr as the address of the beginning of the
- * next outgoing record is set, deduce the other pointers.
- *
- * Note: For TLS, we save the implicit record sequence number
- * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
- * and the caller has to make sure there's space for this.
- */
-
-static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
- mbedtls_ssl_transform *transform )
-{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->out_ctr = ssl->out_hdr + 3;
- ssl->out_len = ssl->out_hdr + 11;
- ssl->out_iv = ssl->out_hdr + 13;
- }
- else
-#endif
- {
- ssl->out_ctr = ssl->out_hdr - 8;
- ssl->out_len = ssl->out_hdr + 3;
- ssl->out_iv = ssl->out_hdr + 5;
- }
-
- /* Adjust out_msg to make space for explicit IV, if used. */
- if( transform != NULL &&
- ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen;
- }
- else
- ssl->out_msg = ssl->out_iv;
-}
-
-/* Once ssl->in_hdr as the address of the beginning of the
- * next incoming record is set, deduce the other pointers.
- *
- * Note: For TLS, we save the implicit record sequence number
- * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
- * and the caller has to make sure there's space for this.
- */
-
-static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
- mbedtls_ssl_transform *transform )
-{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->in_ctr = ssl->in_hdr + 3;
- ssl->in_len = ssl->in_hdr + 11;
- ssl->in_iv = ssl->in_hdr + 13;
- }
- else
-#endif
- {
- ssl->in_ctr = ssl->in_hdr - 8;
- ssl->in_len = ssl->in_hdr + 3;
- ssl->in_iv = ssl->in_hdr + 5;
- }
-
- /* Offset in_msg from in_iv to allow space for explicit IV, if used. */
- if( transform != NULL &&
- ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen;
- }
- else
- ssl->in_msg = ssl->in_iv;
-}
-
/*
* Initialize an SSL context
*/
@@ -7141,31 +3912,12 @@ void mbedtls_ssl_init( mbedtls_ssl_context *ssl )
* Setup an SSL context
*/
-static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
-{
- /* Set the incoming and outgoing record pointers. */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->out_hdr = ssl->out_buf;
- ssl->in_hdr = ssl->in_buf;
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- {
- ssl->out_hdr = ssl->out_buf + 8;
- ssl->in_hdr = ssl->in_buf + 8;
- }
-
- /* Derive other internal pointers. */
- ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
- ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ );
-}
-
int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
const mbedtls_ssl_config *conf )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
ssl->conf = conf;
@@ -7176,23 +3928,33 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
/* Set to NULL in case of an error condition */
ssl->out_buf = NULL;
- ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->in_buf_len = in_buf_len;
+#endif
+ ssl->in_buf = mbedtls_calloc( 1, in_buf_len );
if( ssl->in_buf == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", in_buf_len ) );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto error;
}
- ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->out_buf_len = out_buf_len;
+#endif
+ ssl->out_buf = mbedtls_calloc( 1, out_buf_len );
if( ssl->out_buf == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", out_buf_len ) );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto error;
}
- ssl_reset_in_out_pointers( ssl );
+ mbedtls_ssl_reset_in_out_pointers( ssl );
+
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ memset( &ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info) );
+#endif
if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
goto error;
@@ -7205,6 +3967,10 @@ error:
ssl->conf = NULL;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->in_buf_len = 0;
+ ssl->out_buf_len = 0;
+#endif
ssl->in_buf = NULL;
ssl->out_buf = NULL;
@@ -7230,9 +3996,16 @@ error:
* If partial is non-zero, keep data in the input buffer and client ID.
* (Use when a DTLS client reconnects from the same port.)
*/
-static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
+int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
!defined(MBEDTLS_SSL_SRV_C)
@@ -7242,7 +4015,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
/* Cancel any possibly running timer */
- ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_set_timer( ssl, 0 );
#if defined(MBEDTLS_SSL_RENEGOTIATION)
ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
@@ -7255,7 +4028,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
ssl->in_offt = NULL;
- ssl_reset_in_out_pointers( ssl );
+ mbedtls_ssl_reset_in_out_pointers( ssl );
ssl->in_msgtype = 0;
ssl->in_msglen = 0;
@@ -7264,7 +4037,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->in_epoch = 0;
#endif
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- ssl_dtls_replay_reset( ssl );
+ mbedtls_ssl_dtls_replay_reset( ssl );
#endif
ssl->in_hslen = 0;
@@ -7288,14 +4061,14 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->session_in = NULL;
ssl->session_out = NULL;
- memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN );
+ memset( ssl->out_buf, 0, out_buf_len );
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
if( partial == 0 )
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
{
ssl->in_left = 0;
- memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN );
+ memset( ssl->in_buf, 0, in_buf_len );
}
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
@@ -7351,7 +4124,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
*/
int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl )
{
- return( ssl_session_reset_int( ssl, 0 ) );
+ return( mbedtls_ssl_session_reset_int( ssl, 0 ) );
}
/*
@@ -7462,7 +4235,7 @@ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
ssl->f_get_timer = f_get_timer;
/* Make sure we start with no timer running */
- ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_set_timer( ssl, 0 );
}
#if defined(MBEDTLS_SSL_SRV_C)
@@ -7480,7 +4253,7 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
#if defined(MBEDTLS_SSL_CLI_C)
int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ssl == NULL ||
session == NULL ||
@@ -7490,7 +4263,8 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 )
+ if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate,
+ session ) ) != 0 )
return( ret );
ssl->handshake->resume = 1;
@@ -7572,7 +4346,29 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
{
conf->ca_chain = ca_chain;
conf->ca_crl = ca_crl;
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
+ * cannot be used together. */
+ conf->f_ca_cb = NULL;
+ conf->p_ca_cb = NULL;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+}
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb )
+{
+ conf->f_ca_cb = f_ca_cb;
+ conf->p_ca_cb = p_ca_cb;
+
+ /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
+ * cannot be used together. */
+ conf->ca_chain = NULL;
+ conf->ca_crl = NULL;
}
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@@ -7599,6 +4395,16 @@ void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy )
+{
+ ssl->f_vrfy = f_vrfy;
+ ssl->p_vrfy = p_vrfy;
+}
+#endif
+
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
/*
* Set EC J-PAKE password for current handshake
@@ -7625,24 +4431,24 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
- const unsigned char *psk, size_t psk_len,
- const unsigned char *psk_identity, size_t psk_identity_len )
-{
- if( psk == NULL || psk_identity == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- if( psk_len > MBEDTLS_PSK_MAX_LEN )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
- /* Identity len will be encoded on two bytes */
- if( ( psk_identity_len >> 16 ) != 0 ||
- psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
+static void ssl_conf_remove_psk( mbedtls_ssl_config *conf )
+{
+ /* Remove reference to existing PSK, if any. */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
{
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ /* The maintenance of the PSK key slot is the
+ * user's responsibility. */
+ conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
}
-
+ /* This and the following branch should never
+ * be taken simultaenously as we maintain the
+ * invariant that raw and opaque PSKs are never
+ * configured simultaneously. As a safeguard,
+ * though, `else` is omitted here. */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( conf->psk != NULL )
{
mbedtls_platform_zeroize( conf->psk, conf->psk_len );
@@ -7651,41 +4457,80 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
conf->psk = NULL;
conf->psk_len = 0;
}
+
+ /* Remove reference to PSK identity, if any. */
if( conf->psk_identity != NULL )
{
mbedtls_free( conf->psk_identity );
conf->psk_identity = NULL;
conf->psk_identity_len = 0;
}
+}
- if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ||
- ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL )
+/* This function assumes that PSK identity in the SSL config is unset.
+ * It checks that the provided identity is well-formed and attempts
+ * to make a copy of it in the SSL config.
+ * On failure, the PSK identity in the config remains unset. */
+static int ssl_conf_set_psk_identity( mbedtls_ssl_config *conf,
+ unsigned char const *psk_identity,
+ size_t psk_identity_len )
+{
+ /* Identity len will be encoded on two bytes */
+ if( psk_identity == NULL ||
+ ( psk_identity_len >> 16 ) != 0 ||
+ psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
- mbedtls_free( conf->psk );
- mbedtls_free( conf->psk_identity );
- conf->psk = NULL;
- conf->psk_identity = NULL;
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- conf->psk_len = psk_len;
- conf->psk_identity_len = psk_identity_len;
+ conf->psk_identity = mbedtls_calloc( 1, psk_identity_len );
+ if( conf->psk_identity == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- memcpy( conf->psk, psk, conf->psk_len );
+ conf->psk_identity_len = psk_identity_len;
memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len );
return( 0 );
}
-int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
- const unsigned char *psk, size_t psk_len )
+int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
+ const unsigned char *psk, size_t psk_len,
+ const unsigned char *psk_identity, size_t psk_identity_len )
{
- if( psk == NULL || ssl->handshake == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* Remove opaque/raw PSK + PSK Identity */
+ ssl_conf_remove_psk( conf );
+ /* Check and set raw PSK */
+ if( psk == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ if( psk_len == 0 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( psk_len > MBEDTLS_PSK_MAX_LEN )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ conf->psk_len = psk_len;
+ memcpy( conf->psk, psk, conf->psk_len );
+
+ /* Check and set PSK Identity */
+ ret = ssl_conf_set_psk_identity( conf, psk_identity, psk_identity_len );
+ if( ret != 0 )
+ ssl_conf_remove_psk( conf );
+
+ return( ret );
+}
+
+static void ssl_remove_psk( mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+ {
+ ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ssl->handshake->psk != NULL )
{
mbedtls_platform_zeroize( ssl->handshake->psk,
@@ -7693,6 +4538,18 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
mbedtls_free( ssl->handshake->psk );
ssl->handshake->psk_len = 0;
}
+}
+
+int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
+ const unsigned char *psk, size_t psk_len )
+{
+ if( psk == NULL || ssl->handshake == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( psk_len > MBEDTLS_PSK_MAX_LEN )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ssl_remove_psk( ssl );
if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
@@ -7703,6 +4560,43 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
return( 0 );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
+ psa_key_id_t psk,
+ const unsigned char *psk_identity,
+ size_t psk_identity_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* Clear opaque/raw PSK + PSK Identity, if present. */
+ ssl_conf_remove_psk( conf );
+
+ /* Check and set opaque PSK */
+ if( mbedtls_svc_key_id_is_null( psk ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ conf->psk_opaque = psk;
+
+ /* Check and set PSK Identity */
+ ret = ssl_conf_set_psk_identity( conf, psk_identity,
+ psk_identity_len );
+ if( ret != 0 )
+ ssl_conf_remove_psk( conf );
+
+ return( ret );
+}
+
+int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
+ psa_key_id_t psk )
+{
+ if( ( mbedtls_svc_key_id_is_null( psk ) ) ||
+ ( ssl->handshake == NULL ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ssl_remove_psk( ssl );
+ ssl->handshake->psk_opaque = psk;
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
size_t),
@@ -7711,14 +4605,14 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
conf->f_psk = f_psk;
conf->p_psk = p_psk;
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 ||
( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 )
@@ -7736,7 +4630,7 @@ int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
const unsigned char *dhm_P, size_t P_len,
const unsigned char *dhm_G, size_t G_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 ||
( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 )
@@ -7751,7 +4645,7 @@ int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
@@ -7776,7 +4670,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
}
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Set allowed/preferred hashes for handshake signatures
*/
@@ -7785,7 +4679,7 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
{
conf->sig_hashes = hashes;
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECP_C)
/*
@@ -7889,6 +4783,86 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
}
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
+ int support_mki_value )
+{
+ conf->dtls_srtp_mki_support = support_mki_value;
+}
+
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
+ unsigned char *mki_value,
+ uint16_t mki_len )
+{
+ if( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH )
+ {
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED )
+ {
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
+
+ memcpy( ssl->dtls_srtp_info.mki_value, mki_value, mki_len );
+ ssl->dtls_srtp_info.mki_len = mki_len;
+ return( 0 );
+}
+
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
+ const mbedtls_ssl_srtp_profile *profiles )
+{
+ const mbedtls_ssl_srtp_profile *p;
+ size_t list_size = 0;
+
+ /* check the profiles list: all entry must be valid,
+ * its size cannot be more than the total number of supported profiles, currently 4 */
+ for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET &&
+ list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
+ p++ )
+ {
+ if( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ list_size++;
+ }
+ else
+ {
+ /* unsupported value, stop parsing and set the size to an error value */
+ list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
+ }
+ }
+
+ if( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH )
+ {
+ conf->dtls_srtp_profile_list = NULL;
+ conf->dtls_srtp_profile_list_len = 0;
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ conf->dtls_srtp_profile_list = profiles;
+ conf->dtls_srtp_profile_list_len = list_size;
+
+ return( 0 );
+}
+
+void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl,
+ mbedtls_dtls_srtp_info *dtls_srtp_info )
+{
+ dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile;
+ /* do not copy the mki value if there is no chosen profile */
+ if( dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+ {
+ dtls_srtp_info->mki_len = 0;
+ }
+ else
+ {
+ dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len;
+ memcpy( dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value,
+ ssl->dtls_srtp_info.mki_len );
+ }
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
{
conf->max_major_ver = major;
@@ -8018,6 +4992,14 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
conf->f_export_keys = f_export_keys;
conf->p_export_keys = p_export_keys;
}
+
+void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf,
+ mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
+ void *p_export_keys )
+{
+ conf->f_export_keys_ext = f_export_keys_ext;
+ conf->p_export_keys = p_export_keys;
+}
#endif
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@@ -8060,66 +5042,6 @@ void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
/*
* SSL get accessors
*/
-size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
-{
- return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
-}
-
-int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
-{
- /*
- * Case A: We're currently holding back
- * a message for further processing.
- */
-
- if( ssl->keep_current_message == 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) );
- return( 1 );
- }
-
- /*
- * Case B: Further records are pending in the current datagram.
- */
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->in_left > ssl->next_record_offset )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
- return( 1 );
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- /*
- * Case C: A handshake message is being processed.
- */
-
- if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) );
- return( 1 );
- }
-
- /*
- * Case D: An application data message is being processed
- */
- if( ssl->in_offt != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) );
- return( 1 );
- }
-
- /*
- * In all other cases, the rest of the message can be dropped.
- * As in ssl_get_next_record, this needs to be adapted if
- * we implement support for multiple alerts in single records.
- */
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
- return( 0 );
-}
-
uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl )
{
if( ssl->session != NULL )
@@ -8177,61 +5099,43 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
}
}
-int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl )
{
- size_t transform_expansion = 0;
- const mbedtls_ssl_transform *transform = ssl->transform_out;
- unsigned block_size;
-
- if( transform == NULL )
- return( (int) mbedtls_ssl_hdr_len( ssl ) );
-
-#if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
-#endif
+ size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
+ size_t read_mfl;
- switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
+ /* Use the configured MFL for the client if we're past SERVER_HELLO_DONE */
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+ ssl->state >= MBEDTLS_SSL_SERVER_HELLO_DONE )
{
- case MBEDTLS_MODE_GCM:
- case MBEDTLS_MODE_CCM:
- case MBEDTLS_MODE_CHACHAPOLY:
- case MBEDTLS_MODE_STREAM:
- transform_expansion = transform->minlen;
- break;
-
- case MBEDTLS_MODE_CBC:
-
- block_size = mbedtls_cipher_get_block_size(
- &transform->cipher_ctx_enc );
-
- /* Expansion due to the addition of the MAC. */
- transform_expansion += transform->maclen;
-
- /* Expansion due to the addition of CBC padding;
- * Theoretically up to 256 bytes, but we never use
- * more than the block size of the underlying cipher. */
- transform_expansion += block_size;
-
- /* For TLS 1.1 or higher, an explicit IV is added
- * after the record header. */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- transform_expansion += block_size;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+ return ssl_mfl_code_to_length( ssl->conf->mfl_code );
+ }
- break;
+ /* Check if a smaller max length was negotiated */
+ if( ssl->session_out != NULL )
+ {
+ read_mfl = ssl_mfl_code_to_length( ssl->session_out->mfl_code );
+ if( read_mfl < max_len )
+ {
+ max_len = read_mfl;
+ }
+ }
- default:
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ // During a handshake, use the value being negotiated
+ if( ssl->session_negotiate != NULL )
+ {
+ read_mfl = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code );
+ if( read_mfl < max_len )
+ {
+ max_len = read_mfl;
+ }
}
- return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) );
+ return( max_len );
}
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
+size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl )
{
size_t max_len;
@@ -8256,10 +5160,17 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
return( max_len );
}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
+{
+ return mbedtls_ssl_get_output_max_frag_len( ssl );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
-static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl )
+size_t mbedtls_ssl_get_current_mtu( const mbedtls_ssl_context *ssl )
{
/* Return unlimited mtu for client hello messages to avoid fragmentation. */
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
@@ -8288,16 +5199,16 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
+ const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );
if( max_len > mfl )
max_len = mfl;
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl_get_current_mtu( ssl ) != 0 )
+ if( mbedtls_ssl_get_current_mtu( ssl ) != 0 )
{
- const size_t mtu = ssl_get_current_mtu( ssl );
+ const size_t mtu = mbedtls_ssl_get_current_mtu( ssl );
const int ret = mbedtls_ssl_get_record_expansion( ssl );
const size_t overhead = (size_t) ret;
@@ -8329,12 +5240,17 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ss
if( ssl == NULL || ssl->session == NULL )
return( NULL );
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
return( ssl->session->peer_cert );
+#else
+ return( NULL );
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_CLI_C)
-int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst )
+int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
+ mbedtls_ssl_session *dst )
{
if( ssl == NULL ||
dst == NULL ||
@@ -8344,10 +5260,567 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- return( ssl_session_copy( dst, ssl->session ) );
+ return( mbedtls_ssl_session_copy( dst, ssl->session ) );
}
#endif /* MBEDTLS_SSL_CLI_C */
+const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl )
+{
+ if( ssl == NULL )
+ return( NULL );
+
+ return( ssl->session );
+}
+
+/*
+ * Define ticket header determining Mbed TLS version
+ * and structure of the ticket.
+ */
+
+/*
+ * Define bitflag determining compile-time settings influencing
+ * structure of serialized SSL sessions.
+ */
+
+#if defined(MBEDTLS_HAVE_TIME)
+#define SSL_SERIALIZED_SESSION_CONFIG_TIME 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_TIME 0
+#endif /* MBEDTLS_HAVE_TIME */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#define SSL_SERIALIZED_SESSION_CONFIG_CRT 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_CRT 0
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 0
+#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+#define SSL_SERIALIZED_SESSION_CONFIG_MFL 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_MFL 0
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 0
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+#define SSL_SERIALIZED_SESSION_CONFIG_ETM 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_ETM 0
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0
+#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1
+#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2
+#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3
+#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT 4
+#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 5
+#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 6
+
+#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \
+ ( (uint16_t) ( \
+ ( SSL_SERIALIZED_SESSION_CONFIG_TIME << SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_CRT << SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET << SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC << SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT ) ) )
+
+static unsigned char ssl_serialized_session_header[] = {
+ MBEDTLS_VERSION_MAJOR,
+ MBEDTLS_VERSION_MINOR,
+ MBEDTLS_VERSION_PATCH,
+ MBEDTLS_BYTE_1( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_0( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+};
+
+/*
+ * Serialize a session in the following format:
+ * (in the presentation language of TLS, RFC 8446 section 3)
+ *
+ * opaque mbedtls_version[3]; // major, minor, patch
+ * opaque session_format[2]; // version-specific 16-bit field determining
+ * // the format of the remaining
+ * // serialized data.
+ *
+ * Note: When updating the format, remember to keep
+ * these version+format bytes.
+ *
+ * // In this version, `session_format` determines
+ * // the setting of those compile-time
+ * // configuration options which influence
+ * // the structure of mbedtls_ssl_session.
+ * uint64 start_time;
+ * uint8 ciphersuite[2]; // defined by the standard
+ * uint8 compression; // 0 or 1
+ * uint8 session_id_len; // at most 32
+ * opaque session_id[32];
+ * opaque master[48]; // fixed length in the standard
+ * uint32 verify_result;
+ * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
+ * opaque ticket<0..2^24-1>; // length 0 means no ticket
+ * uint32 ticket_lifetime;
+ * uint8 mfl_code; // up to 255 according to standard
+ * uint8 trunc_hmac; // 0 or 1
+ * uint8 encrypt_then_mac; // 0 or 1
+ *
+ * The order is the same as in the definition of the structure, except
+ * verify_result is put before peer_cert so that all mandatory fields come
+ * together in one block.
+ */
+static int ssl_session_save( const mbedtls_ssl_session *session,
+ unsigned char omit_header,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t used = 0;
+#if defined(MBEDTLS_HAVE_TIME)
+ uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+
+ if( !omit_header )
+ {
+ /*
+ * Add version identifier
+ */
+
+ used += sizeof( ssl_serialized_session_header );
+
+ if( used <= buf_len )
+ {
+ memcpy( p, ssl_serialized_session_header,
+ sizeof( ssl_serialized_session_header ) );
+ p += sizeof( ssl_serialized_session_header );
+ }
+ }
+
+ /*
+ * Time
+ */
+#if defined(MBEDTLS_HAVE_TIME)
+ used += 8;
+
+ if( used <= buf_len )
+ {
+ start = (uint64_t) session->start;
+
+ MBEDTLS_PUT_UINT64_BE( start, p, 0 );
+ p += 8;
+ }
+#endif /* MBEDTLS_HAVE_TIME */
+
+ /*
+ * Basic mandatory fields
+ */
+ used += 2 /* ciphersuite */
+ + 1 /* compression */
+ + 1 /* id_len */
+ + sizeof( session->id )
+ + sizeof( session->master )
+ + 4; /* verify_result */
+
+ if( used <= buf_len )
+ {
+ MBEDTLS_PUT_UINT16_BE( session->ciphersuite, p, 0 );
+ p += 2;
+
+ *p++ = MBEDTLS_BYTE_0( session->compression );
+
+ *p++ = MBEDTLS_BYTE_0( session->id_len );
+ memcpy( p, session->id, 32 );
+ p += 32;
+
+ memcpy( p, session->master, 48 );
+ p += 48;
+
+ MBEDTLS_PUT_UINT32_BE( session->verify_result, p, 0 );
+ p += 4;
+ }
+
+ /*
+ * Peer's end-entity certificate
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if( session->peer_cert == NULL )
+ cert_len = 0;
+ else
+ cert_len = session->peer_cert->raw.len;
+
+ used += 3 + cert_len;
+
+ if( used <= buf_len )
+ {
+ *p++ = MBEDTLS_BYTE_2( cert_len );
+ *p++ = MBEDTLS_BYTE_1( cert_len );
+ *p++ = MBEDTLS_BYTE_0( cert_len );
+
+ if( session->peer_cert != NULL )
+ {
+ memcpy( p, session->peer_cert->raw.p, cert_len );
+ p += cert_len;
+ }
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( session->peer_cert_digest != NULL )
+ {
+ used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
+ if( used <= buf_len )
+ {
+ *p++ = (unsigned char) session->peer_cert_digest_type;
+ *p++ = (unsigned char) session->peer_cert_digest_len;
+ memcpy( p, session->peer_cert_digest,
+ session->peer_cert_digest_len );
+ p += session->peer_cert_digest_len;
+ }
+ }
+ else
+ {
+ used += 2;
+ if( used <= buf_len )
+ {
+ *p++ = (unsigned char) MBEDTLS_MD_NONE;
+ *p++ = 0;
+ }
+ }
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Session ticket if any, plus associated data
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
+
+ if( used <= buf_len )
+ {
+ *p++ = MBEDTLS_BYTE_2( session->ticket_len );
+ *p++ = MBEDTLS_BYTE_1( session->ticket_len );
+ *p++ = MBEDTLS_BYTE_0( session->ticket_len );
+
+ if( session->ticket != NULL )
+ {
+ memcpy( p, session->ticket, session->ticket_len );
+ p += session->ticket_len;
+ }
+
+ MBEDTLS_PUT_UINT32_BE( session->ticket_lifetime, p, 0 );
+ p += 4;
+ }
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+ /*
+ * Misc extension-related info
+ */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ used += 1;
+
+ if( used <= buf_len )
+ *p++ = session->mfl_code;
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ used += 1;
+
+ if( used <= buf_len )
+ *p++ = (unsigned char)( ( session->trunc_hmac ) & 0xFF );
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ used += 1;
+
+ if( used <= buf_len )
+ *p++ = MBEDTLS_BYTE_0( session->encrypt_then_mac );
+#endif
+
+ /* Done */
+ *olen = used;
+
+ if( used > buf_len )
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+ return( 0 );
+}
+
+/*
+ * Public wrapper for ssl_session_save()
+ */
+int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen )
+{
+ return( ssl_session_save( session, 0, buf, buf_len, olen ) );
+}
+
+/*
+ * Deserialize session, see mbedtls_ssl_session_save() for format.
+ *
+ * This internal version is wrapped by a public function that cleans up in
+ * case of error, and has an extra option omit_header.
+ */
+static int ssl_session_load( mbedtls_ssl_session *session,
+ unsigned char omit_header,
+ const unsigned char *buf,
+ size_t len )
+{
+ const unsigned char *p = buf;
+ const unsigned char * const end = buf + len;
+#if defined(MBEDTLS_HAVE_TIME)
+ uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ if( !omit_header )
+ {
+ /*
+ * Check version identifier
+ */
+
+ if( (size_t)( end - p ) < sizeof( ssl_serialized_session_header ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( memcmp( p, ssl_serialized_session_header,
+ sizeof( ssl_serialized_session_header ) ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_VERSION_MISMATCH );
+ }
+ p += sizeof( ssl_serialized_session_header );
+ }
+
+ /*
+ * Time
+ */
+#if defined(MBEDTLS_HAVE_TIME)
+ if( 8 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ start = ( (uint64_t) p[0] << 56 ) |
+ ( (uint64_t) p[1] << 48 ) |
+ ( (uint64_t) p[2] << 40 ) |
+ ( (uint64_t) p[3] << 32 ) |
+ ( (uint64_t) p[4] << 24 ) |
+ ( (uint64_t) p[5] << 16 ) |
+ ( (uint64_t) p[6] << 8 ) |
+ ( (uint64_t) p[7] );
+ p += 8;
+
+ session->start = (time_t) start;
+#endif /* MBEDTLS_HAVE_TIME */
+
+ /*
+ * Basic mandatory fields
+ */
+ if( 2 + 1 + 1 + 32 + 48 + 4 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->ciphersuite = ( p[0] << 8 ) | p[1];
+ p += 2;
+
+ session->compression = *p++;
+
+ session->id_len = *p++;
+ memcpy( session->id, p, 32 );
+ p += 32;
+
+ memcpy( session->master, p, 48 );
+ p += 48;
+
+ session->verify_result = ( (uint32_t) p[0] << 24 ) |
+ ( (uint32_t) p[1] << 16 ) |
+ ( (uint32_t) p[2] << 8 ) |
+ ( (uint32_t) p[3] );
+ p += 4;
+
+ /* Immediately clear invalid pointer values that have been read, in case
+ * we exit early before we replaced them with valid ones. */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ session->peer_cert = NULL;
+#else
+ session->peer_cert_digest = NULL;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ session->ticket = NULL;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+ /*
+ * Peer certificate
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* Deserialize CRT from the end of the ticket. */
+ if( 3 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
+ p += 3;
+
+ if( cert_len != 0 )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( cert_len > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+
+ if( session->peer_cert == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ mbedtls_x509_crt_init( session->peer_cert );
+
+ if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
+ p, cert_len ) ) != 0 )
+ {
+ mbedtls_x509_crt_free( session->peer_cert );
+ mbedtls_free( session->peer_cert );
+ session->peer_cert = NULL;
+ return( ret );
+ }
+
+ p += cert_len;
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /* Deserialize CRT digest from the end of the ticket. */
+ if( 2 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
+ session->peer_cert_digest_len = (size_t) *p++;
+
+ if( session->peer_cert_digest_len != 0 )
+ {
+ const mbedtls_md_info_t *md_info =
+ mbedtls_md_info_from_type( session->peer_cert_digest_type );
+ if( md_info == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ if( session->peer_cert_digest_len != mbedtls_md_get_size( md_info ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( session->peer_cert_digest_len > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->peer_cert_digest =
+ mbedtls_calloc( 1, session->peer_cert_digest_len );
+ if( session->peer_cert_digest == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ memcpy( session->peer_cert_digest, p,
+ session->peer_cert_digest_len );
+ p += session->peer_cert_digest_len;
+ }
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Session ticket and associated data
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ if( 3 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->ticket_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
+ p += 3;
+
+ if( session->ticket_len != 0 )
+ {
+ if( session->ticket_len > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->ticket = mbedtls_calloc( 1, session->ticket_len );
+ if( session->ticket == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ memcpy( session->ticket, p, session->ticket_len );
+ p += session->ticket_len;
+ }
+
+ if( 4 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->ticket_lifetime = ( (uint32_t) p[0] << 24 ) |
+ ( (uint32_t) p[1] << 16 ) |
+ ( (uint32_t) p[2] << 8 ) |
+ ( (uint32_t) p[3] );
+ p += 4;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+ /*
+ * Misc extension-related info
+ */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ if( 1 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->mfl_code = *p++;
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ if( 1 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->trunc_hmac = *p++;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ if( 1 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->encrypt_then_mac = *p++;
+#endif
+
+ /* Done, should have consumed entire buffer */
+ if( p != end )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ return( 0 );
+}
+
+/*
+ * Deserialize session: public wrapper for error cleaning
+ */
+int mbedtls_ssl_session_load( mbedtls_ssl_session *session,
+ const unsigned char *buf,
+ size_t len )
+{
+ int ret = ssl_session_load( session, 0, buf, len );
+
+ if( ret != 0 )
+ mbedtls_ssl_session_free( session );
+
+ return( ret );
+}
+
/*
* Perform a single step of the SSL handshake
*/
@@ -8377,11 +5850,24 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
{
int ret = 0;
+ /* Sanity checks */
+
if( ssl == NULL || ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
+ "mbedtls_ssl_set_timer_cb() for DTLS" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
+ /* Main handshake loop */
while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
ret = mbedtls_ssl_handshake_step( ssl );
@@ -8402,7 +5888,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
*/
static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) );
@@ -8431,9 +5917,9 @@ static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
* If the handshake doesn't complete due to waiting for I/O, it will continue
* during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
*/
-static int ssl_start_renegotiation( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_start_renegotiation( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
@@ -8505,9 +5991,9 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl )
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_start_renegotiation( ssl ) ) != 0 )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_start_renegotiation", ret );
return( ret );
}
}
@@ -8523,708 +6009,785 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl )
return( ret );
}
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
-/*
- * Check record counters and renegotiate if they're above the limit.
- */
-static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
{
- size_t ep_len = ssl_ep_len( ssl );
- int in_ctr_cmp;
- int out_ctr_cmp;
+ mbedtls_ssl_key_cert *cur = key_cert, *next;
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
- ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
+ while( cur != NULL )
{
- return( 0 );
+ next = cur->next;
+ mbedtls_free( cur );
+ cur = next;
}
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
- in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
- ssl->conf->renego_period + ep_len, 8 - ep_len );
- out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
- ssl->conf->renego_period + ep_len, 8 - ep_len );
+void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+ if( handshake == NULL )
+ return;
- if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
{
- return( 0 );
+ ssl->conf->f_async_cancel( ssl );
+ handshake->async_in_progress = 0;
}
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
- return( mbedtls_ssl_renegotiate( ssl ) );
-}
-#endif /* MBEDTLS_SSL_RENEGOTIATION */
-
-/*
- * Receive application data decrypted from the SSL layer
- */
-int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
-{
- int ret;
- size_t n;
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_1)
+ mbedtls_md5_free( &handshake->fin_md5 );
+ mbedtls_sha1_free( &handshake->fin_sha1 );
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &handshake->fin_sha256_psa );
+#else
+ mbedtls_sha256_free( &handshake->fin_sha256 );
+#endif
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &handshake->fin_sha384_psa );
+#else
+ mbedtls_sha512_free( &handshake->fin_sha512 );
+#endif
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+#if defined(MBEDTLS_DHM_C)
+ mbedtls_dhm_free( &handshake->dhm_ctx );
+#endif
+#if defined(MBEDTLS_ECDH_C)
+ mbedtls_ecdh_free( &handshake->ecdh_ctx );
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
+#if defined(MBEDTLS_SSL_CLI_C)
+ mbedtls_free( handshake->ecjpake_cache );
+ handshake->ecjpake_cache = NULL;
+ handshake->ecjpake_cache_len = 0;
+#endif
+#endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ /* explicit void pointer cast for buggy MS compiler */
+ mbedtls_free( (void *) handshake->curves );
+#endif
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+ if( handshake->psk != NULL )
{
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- if( ssl->handshake != NULL &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
- return( ret );
- }
+ mbedtls_platform_zeroize( handshake->psk, handshake->psk_len );
+ mbedtls_free( handshake->psk );
}
#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
/*
- * Check if renegotiation is necessary and/or handshake is
- * in process. If yes, perform/continue, and fall through
- * if an unexpected packet is received while the client
- * is waiting for the ServerHello.
- *
- * (There is no equivalent to the last condition on
- * the server-side as it is not treated as within
- * a handshake while waiting for the ClientHello
- * after a renegotiation request.)
+ * Free only the linked list wrapper, not the keys themselves
+ * since the belong to the SNI callback
*/
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- ret = ssl_check_ctr_renegotiate( ssl );
- if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
- ret != 0 )
+ if( handshake->sni_key_cert != NULL )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
- return( ret );
- }
-#endif
+ mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- ret = mbedtls_ssl_handshake( ssl );
- if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
- ret != 0 )
+ while( cur != NULL )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
- return( ret );
+ next = cur->next;
+ mbedtls_free( cur );
+ cur = next;
}
}
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
- /* Loop as long as no application data record is available */
- while( ssl->in_offt == NULL )
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx );
+ if( handshake->ecrs_peer_cert != NULL )
{
- /* Start timer if not already running */
- if( ssl->f_get_timer != NULL &&
- ssl->f_get_timer( ssl->p_timer ) == -1 )
- {
- ssl_set_timer( ssl, ssl->conf->read_timeout );
- }
-
- if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
- return( 0 );
+ mbedtls_x509_crt_free( handshake->ecrs_peer_cert );
+ mbedtls_free( handshake->ecrs_peer_cert );
+ }
+#endif
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_pk_free( &handshake->peer_pubkey );
+#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- if( ssl->in_msglen == 0 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- /*
- * OpenSSL sends empty messages to randomize the IV
- */
- if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
- return( 0 );
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ mbedtls_free( handshake->verify_cookie );
+ mbedtls_ssl_flight_free( handshake->flight );
+ mbedtls_ssl_buffering_free( ssl );
+#endif
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- }
+#if defined(MBEDTLS_ECDH_C) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_destroy_key( handshake->ecdh_psa_privkey );
+#endif /* MBEDTLS_ECDH_C && MBEDTLS_USE_PSA_CRYPTO */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
+ mbedtls_platform_zeroize( handshake,
+ sizeof( mbedtls_ssl_handshake_params ) );
- /*
- * - For client-side, expect SERVER_HELLO_REQUEST.
- * - For server-side, expect CLIENT_HELLO.
- * - Fail (TLS) or silently drop record (DTLS) in other cases.
- */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ /* If the buffers are too big - reallocate. Because of the way Mbed TLS
+ * processes datagrams and the fact that a datagram is allowed to have
+ * several records in it, it is possible that the I/O buffers are not
+ * empty at this stage */
+ handle_buffer_resizing( ssl, 1, mbedtls_ssl_get_input_buflen( ssl ),
+ mbedtls_ssl_get_output_buflen( ssl ) );
+#endif
+}
-#if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
- ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
- ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
+void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
+{
+ if( session == NULL )
+ return;
- /* With DTLS, drop the packet (probably from last handshake) */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- continue;
- }
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ ssl_clear_peer_cert( session );
#endif
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-
-#if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
- /* With DTLS, drop the packet (probably from last handshake) */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- continue;
- }
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ mbedtls_free( session->ticket );
#endif
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
-#endif /* MBEDTLS_SSL_SRV_C */
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- /* Determine whether renegotiation attempt should be accepted */
- if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
- ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation ==
- MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
- {
- /*
- * Accept renegotiation request
- */
+ mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) );
+}
- /* DTLS clients need to know renego is server-initiated */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- {
- ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
- }
-#endif
- ret = ssl_start_renegotiation( ssl );
- if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
- ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
- return( ret );
- }
- }
- else
-#endif /* MBEDTLS_SSL_RENEGOTIATION */
- {
- /*
- * Refuse renegotiation
- */
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 1u
+#else
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 0u
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- /* SSLv3 does not have a "no_renegotiation" warning, so
- we send a fatal alert and abort the connection. */
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
- {
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_WARNING,
- MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
- {
- return( ret );
- }
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 1u
+#else
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 0u
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
- /* At this point, we don't know whether the renegotiation has been
- * completed or not. The cases to consider are the following:
- * 1) The renegotiation is complete. In this case, no new record
- * has been read yet.
- * 2) The renegotiation is incomplete because the client received
- * an application data record while awaiting the ServerHello.
- * 3) The renegotiation is incomplete because the client received
- * a non-handshake, non-application data message while awaiting
- * the ServerHello.
- * In each of these case, looping will be the proper action:
- * - For 1), the next iteration will read a new record and check
- * if it's application data.
- * - For 2), the loop condition isn't satisfied as application data
- * is present, hence continue is the same as break
- * - For 3), the loop condition is satisfied and read_record
- * will re-deliver the message that was held back by the client
- * when expecting the ServerHello.
- */
- continue;
- }
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ssl->conf->renego_max_records >= 0 )
- {
- if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
- "but not honored by client" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- }
- }
-#endif /* MBEDTLS_SSL_RENEGOTIATION */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 1u
+#else
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 0u
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
- /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
+#if defined(MBEDTLS_SSL_ALPN)
+#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 1u
+#else
+#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 0u
+#endif /* MBEDTLS_SSL_ALPN */
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT 0
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT 1
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT 2
+#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT 3
+
+#define SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG \
+ ( (uint32_t) ( \
+ ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT ) | \
+ ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT ) | \
+ ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT ) | \
+ ( SSL_SERIALIZED_CONTEXT_CONFIG_ALPN << SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT ) | \
+ 0u ) )
+
+static unsigned char ssl_serialized_context_header[] = {
+ MBEDTLS_VERSION_MAJOR,
+ MBEDTLS_VERSION_MINOR,
+ MBEDTLS_VERSION_PATCH,
+ MBEDTLS_BYTE_1( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_0( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_2( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_1( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_0( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
+};
- ssl->in_offt = ssl->in_msg;
+/*
+ * Serialize a full SSL context
+ *
+ * The format of the serialized data is:
+ * (in the presentation language of TLS, RFC 8446 section 3)
+ *
+ * // header
+ * opaque mbedtls_version[3]; // major, minor, patch
+ * opaque context_format[5]; // version-specific field determining
+ * // the format of the remaining
+ * // serialized data.
+ * Note: When updating the format, remember to keep these
+ * version+format bytes. (We may make their size part of the API.)
+ *
+ * // session sub-structure
+ * opaque session<1..2^32-1>; // see mbedtls_ssl_session_save()
+ * // transform sub-structure
+ * uint8 random[64]; // ServerHello.random+ClientHello.random
+ * uint8 in_cid<0..2^8-1> // Connection ID: expected incoming value
+ * uint8 out_cid<0..2^8-1> // Connection ID: outgoing value to use
+ * // fields from ssl_context
+ * uint32 badmac_seen; // DTLS: number of records with failing MAC
+ * uint64 in_window_top; // DTLS: last validated record seq_num
+ * uint64 in_window; // DTLS: bitmask for replay protection
+ * uint8 disable_datagram_packing; // DTLS: only one record per datagram
+ * uint64 cur_out_ctr; // Record layer: outgoing sequence number
+ * uint16 mtu; // DTLS: path mtu (max outgoing fragment size)
+ * uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol
+ *
+ * Note that many fields of the ssl_context or sub-structures are not
+ * serialized, as they fall in one of the following categories:
+ *
+ * 1. forced value (eg in_left must be 0)
+ * 2. pointer to dynamically-allocated memory (eg session, transform)
+ * 3. value can be re-derived from other data (eg session keys from MS)
+ * 4. value was temporary (eg content of input buffer)
+ * 5. value will be provided by the user again (eg I/O callbacks and context)
+ */
+int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t used = 0;
+ size_t session_len;
+ int ret = 0;
- /* We're going to return something now, cancel timer,
- * except if handshake (renegotiation) is in progress */
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- ssl_set_timer( ssl, 0 );
+ /*
+ * Enforce usage restrictions, see "return BAD_INPUT_DATA" in
+ * this function's documentation.
+ *
+ * These are due to assumptions/limitations in the implementation. Some of
+ * them are likely to stay (no handshake in progress) some might go away
+ * (only DTLS) but are currently used to simplify the implementation.
+ */
+ /* The initial handshake must be over */
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Initial handshake isn't over" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ if( ssl->handshake != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Handshake isn't completed" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* Double-check that sub-structures are indeed ready */
+ if( ssl->transform == NULL || ssl->session == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Serialised structures aren't ready" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* There must be no pending incoming or outgoing data */
+ if( mbedtls_ssl_check_pending( ssl ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "There is pending incoming data" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ if( ssl->out_left != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "There is pending outgoing data" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* Protocol must be DLTS, not TLS */
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only DTLS is supported" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* Version must be 1.2 */
+ if( ssl->major_ver != MBEDTLS_SSL_MAJOR_VERSION_3 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only version 1.2 supported" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only version 1.2 supported" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* We must be using an AEAD ciphersuite */
+ if( mbedtls_ssl_transform_uses_aead( ssl->transform ) != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only AEAD ciphersuites supported" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* Renegotiation must not be enabled */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ if( ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Renegotiation must not be enabled" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+#endif
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* If we requested renego but received AppData, resend HelloRequest.
- * Do it now, after setting in_offt, to avoid taking this branch
- * again if ssl_write_hello_request() returns WANT_WRITE */
-#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
- return( ret );
- }
- }
-#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ /*
+ * Version and format identifier
+ */
+ used += sizeof( ssl_serialized_context_header );
+
+ if( used <= buf_len )
+ {
+ memcpy( p, ssl_serialized_context_header,
+ sizeof( ssl_serialized_context_header ) );
+ p += sizeof( ssl_serialized_context_header );
}
- n = ( len < ssl->in_msglen )
- ? len : ssl->in_msglen;
+ /*
+ * Session (length + data)
+ */
+ ret = ssl_session_save( ssl->session, 1, NULL, 0, &session_len );
+ if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL )
+ return( ret );
+
+ used += 4 + session_len;
+ if( used <= buf_len )
+ {
+ MBEDTLS_PUT_UINT32_BE( session_len, p, 0 );
+ p += 4;
- memcpy( buf, ssl->in_offt, n );
- ssl->in_msglen -= n;
+ ret = ssl_session_save( ssl->session, 1,
+ p, session_len, &session_len );
+ if( ret != 0 )
+ return( ret );
- /* Zeroising the plaintext buffer to erase unused application data
- from the memory. */
- mbedtls_platform_zeroize( ssl->in_offt, n );
+ p += session_len;
+ }
- if( ssl->in_msglen == 0 )
+ /*
+ * Transform
+ */
+ used += sizeof( ssl->transform->randbytes );
+ if( used <= buf_len )
{
- /* all bytes consumed */
- ssl->in_offt = NULL;
- ssl->keep_current_message = 0;
+ memcpy( p, ssl->transform->randbytes,
+ sizeof( ssl->transform->randbytes ) );
+ p += sizeof( ssl->transform->randbytes );
}
- else
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ used += 2 + ssl->transform->in_cid_len + ssl->transform->out_cid_len;
+ if( used <= buf_len )
{
- /* more data available */
- ssl->in_offt += n;
+ *p++ = ssl->transform->in_cid_len;
+ memcpy( p, ssl->transform->in_cid, ssl->transform->in_cid_len );
+ p += ssl->transform->in_cid_len;
+
+ *p++ = ssl->transform->out_cid_len;
+ memcpy( p, ssl->transform->out_cid, ssl->transform->out_cid_len );
+ p += ssl->transform->out_cid_len;
}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
+ /*
+ * Saved fields from top-level ssl_context structure
+ */
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ used += 4;
+ if( used <= buf_len )
+ {
+ MBEDTLS_PUT_UINT32_BE( ssl->badmac_seen, p, 0 );
+ p += 4;
+ }
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
- return( (int) n );
-}
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ used += 16;
+ if( used <= buf_len )
+ {
+ MBEDTLS_PUT_UINT64_BE( ssl->in_window_top, p, 0 );
+ p += 8;
-/*
- * Send application data to be encrypted by the SSL layer, taking care of max
- * fragment length and buffer size.
- *
- * According to RFC 5246 Section 6.2.1:
- *
- * Zero-length fragments of Application data MAY be sent as they are
- * potentially useful as a traffic analysis countermeasure.
- *
- * Therefore, it is possible that the input message length is 0 and the
- * corresponding return code is 0 on success.
- */
-static int ssl_write_real( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
-{
- int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
- const size_t max_len = (size_t) ret;
+ MBEDTLS_PUT_UINT64_BE( ssl->in_window, p, 0 );
+ p += 8;
+ }
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
- if( ret < 0 )
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ used += 1;
+ if( used <= buf_len )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret );
- return( ret );
+ *p++ = ssl->disable_datagram_packing;
}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
- if( len > max_len )
+ used += 8;
+ if( used <= buf_len )
{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
- "maximum fragment length: %d > %d",
- len, max_len ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- else
-#endif
- len = max_len;
+ memcpy( p, ssl->cur_out_ctr, 8 );
+ p += 8;
}
- if( ssl->out_left != 0 )
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ used += 2;
+ if( used <= buf_len )
{
- /*
- * The user has previously tried to send the data and
- * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
- * written. In this case, we expect the high-level write function
- * (e.g. mbedtls_ssl_write()) to be called with the same parameters
- */
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
- return( ret );
- }
+ MBEDTLS_PUT_UINT16_BE( ssl->mtu, p, 0 );
+ p += 2;
}
- else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_ALPN)
{
- /*
- * The user is trying to send a message the first time, so we need to
- * copy the data into the internal buffers and setup the data structure
- * to keep track of partial writes
- */
- ssl->out_msglen = len;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
- memcpy( ssl->out_msg, buf, len );
+ const uint8_t alpn_len = ssl->alpn_chosen
+ ? (uint8_t) strlen( ssl->alpn_chosen )
+ : 0;
- if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+ used += 1 + alpn_len;
+ if( used <= buf_len )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
+ *p++ = alpn_len;
+
+ if( ssl->alpn_chosen != NULL )
+ {
+ memcpy( p, ssl->alpn_chosen, alpn_len );
+ p += alpn_len;
+ }
}
}
+#endif /* MBEDTLS_SSL_ALPN */
+
+ /*
+ * Done
+ */
+ *olen = used;
- return( (int) len );
+ if( used > buf_len )
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "saved context", buf, used );
+
+ return( mbedtls_ssl_session_reset_int( ssl, 0 ) );
}
/*
- * Write application data, doing 1/n-1 splitting if necessary.
- *
- * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
- * then the caller will call us again with the same arguments, so
- * remember whether we already did the split or not.
+ * Helper to get TLS 1.2 PRF from ciphersuite
+ * (Duplicates bits of logic from ssl_set_handshake_prfs().)
*/
-#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
-static int ssl_write_split( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
+typedef int (*tls_prf_fn)( const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen );
+static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id )
{
- int ret;
-
- if( ssl->conf->cbc_record_splitting ==
- MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
- len <= 1 ||
- ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
- mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
- != MBEDTLS_MODE_CBC )
- {
- return( ssl_write_real( ssl, buf, len ) );
- }
-
- if( ssl->split_done == 0 )
- {
- if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
- return( ret );
- ssl->split_done = 1;
- }
-
- if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
- return( ret );
- ssl->split_done = 0;
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
+ mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
- return( ret + 1 );
+ if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+ return( tls_prf_sha384 );
+#else
+ (void) ciphersuite_id;
+#endif
+ return( tls_prf_sha256 );
}
-#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
/*
- * Write application data (public-facing wrapper)
+ * Deserialize context, see mbedtls_ssl_context_save() for format.
+ *
+ * This internal version is wrapped by a public function that cleans up in
+ * case of error.
*/
-int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
+static int ssl_context_load( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
{
- int ret;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
+ const unsigned char *p = buf;
+ const unsigned char * const end = buf + len;
+ size_t session_len;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( ssl == NULL || ssl->conf == NULL )
+ /*
+ * The context should have been freshly setup or reset.
+ * Give the user an error in case of obvious misuse.
+ * (Checking session is useful because it won't be NULL if we're
+ * renegotiating, or if the user mistakenly loaded a session first.)
+ */
+ if( ssl->state != MBEDTLS_SSL_HELLO_REQUEST ||
+ ssl->session != NULL )
+ {
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /*
+ * We can't check that the config matches the initial one, but we can at
+ * least check it matches the requirements for serializing.
+ */
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ ssl->conf->max_major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
+ ssl->conf->min_major_ver > MBEDTLS_SSL_MAJOR_VERSION_3 ||
+ ssl->conf->max_minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ||
+ ssl->conf->min_minor_ver > MBEDTLS_SSL_MINOR_VERSION_3 ||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
- return( ret );
- }
+ ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
#endif
-
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ 0 )
{
- if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
- return( ret );
- }
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
-#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- ret = ssl_write_split( ssl, buf, len );
-#else
- ret = ssl_write_real( ssl, buf, len );
-#endif
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "context to load", buf, len );
- return( ret );
-}
+ /*
+ * Check version identifier
+ */
+ if( (size_t)( end - p ) < sizeof( ssl_serialized_context_header ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-/*
- * Notify the peer that the connection is being closed
- */
-int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
-{
- int ret;
+ if( memcmp( p, ssl_serialized_context_header,
+ sizeof( ssl_serialized_context_header ) ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_VERSION_MISMATCH );
+ }
+ p += sizeof( ssl_serialized_context_header );
- if( ssl == NULL || ssl->conf == NULL )
+ /*
+ * Session
+ */
+ if( (size_t)( end - p ) < 4 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
+ session_len = ( (size_t) p[0] << 24 ) |
+ ( (size_t) p[1] << 16 ) |
+ ( (size_t) p[2] << 8 ) |
+ ( (size_t) p[3] );
+ p += 4;
- if( ssl->out_left != 0 )
- return( mbedtls_ssl_flush_output( ssl ) );
+ /* This has been allocated by ssl_handshake_init(), called by
+ * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */
+ ssl->session = ssl->session_negotiate;
+ ssl->session_in = ssl->session;
+ ssl->session_out = ssl->session;
+ ssl->session_negotiate = NULL;
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ if( (size_t)( end - p ) < session_len )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ret = ssl_session_load( ssl->session, 1, p, session_len );
+ if( ret != 0 )
{
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_WARNING,
- MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
- return( ret );
- }
+ mbedtls_ssl_session_free( ssl->session );
+ return( ret );
}
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
+ p += session_len;
- return( 0 );
-}
+ /*
+ * Transform
+ */
-void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
-{
- if( transform == NULL )
- return;
+ /* This has been allocated by ssl_handshake_init(), called by
+ * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */
+ ssl->transform = ssl->transform_negotiate;
+ ssl->transform_in = ssl->transform;
+ ssl->transform_out = ssl->transform;
+ ssl->transform_negotiate = NULL;
+
+ /* Read random bytes and populate structure */
+ if( (size_t)( end - p ) < sizeof( ssl->transform->randbytes ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ ret = ssl_populate_transform( ssl->transform,
+ ssl->session->ciphersuite,
+ ssl->session->master,
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ ssl->session->encrypt_then_mac,
+#endif
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ ssl->session->trunc_hmac,
+#endif
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
#if defined(MBEDTLS_ZLIB_SUPPORT)
- deflateEnd( &transform->ctx_deflate );
- inflateEnd( &transform->ctx_inflate );
+ ssl->session->compression,
#endif
+ ssl_tls12prf_from_cs( ssl->session->ciphersuite ),
+ p, /* currently pointing to randbytes */
+ MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */
+ ssl->conf->endpoint,
+ ssl );
+ if( ret != 0 )
+ return( ret );
- mbedtls_cipher_free( &transform->cipher_ctx_enc );
- mbedtls_cipher_free( &transform->cipher_ctx_dec );
+ p += sizeof( ssl->transform->randbytes );
- mbedtls_md_free( &transform->md_ctx_enc );
- mbedtls_md_free( &transform->md_ctx_dec );
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* Read connection IDs and store them */
+ if( (size_t)( end - p ) < 1 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
-}
+ ssl->transform->in_cid_len = *p++;
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
-{
- mbedtls_ssl_key_cert *cur = key_cert, *next;
+ if( (size_t)( end - p ) < ssl->transform->in_cid_len + 1u )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- while( cur != NULL )
- {
- next = cur->next;
- mbedtls_free( cur );
- cur = next;
- }
-}
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+ memcpy( ssl->transform->in_cid, p, ssl->transform->in_cid_len );
+ p += ssl->transform->in_cid_len;
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ ssl->transform->out_cid_len = *p++;
-static void ssl_buffering_free( mbedtls_ssl_context *ssl )
-{
- unsigned offset;
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ if( (size_t)( end - p ) < ssl->transform->out_cid_len )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( hs == NULL )
- return;
+ memcpy( ssl->transform->out_cid, p, ssl->transform->out_cid_len );
+ p += ssl->transform->out_cid_len;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
- ssl_free_buffered_record( ssl );
+ /*
+ * Saved fields from top-level ssl_context structure
+ */
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ if( (size_t)( end - p ) < 4 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
- ssl_buffering_free_slot( ssl, offset );
-}
+ ssl->badmac_seen = ( (uint32_t) p[0] << 24 ) |
+ ( (uint32_t) p[1] << 16 ) |
+ ( (uint32_t) p[2] << 8 ) |
+ ( (uint32_t) p[3] );
+ p += 4;
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
-static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
- uint8_t slot )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ if( (size_t)( end - p ) < 16 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS )
- return;
+ ssl->in_window_top = ( (uint64_t) p[0] << 56 ) |
+ ( (uint64_t) p[1] << 48 ) |
+ ( (uint64_t) p[2] << 40 ) |
+ ( (uint64_t) p[3] << 32 ) |
+ ( (uint64_t) p[4] << 24 ) |
+ ( (uint64_t) p[5] << 16 ) |
+ ( (uint64_t) p[6] << 8 ) |
+ ( (uint64_t) p[7] );
+ p += 8;
+
+ ssl->in_window = ( (uint64_t) p[0] << 56 ) |
+ ( (uint64_t) p[1] << 48 ) |
+ ( (uint64_t) p[2] << 40 ) |
+ ( (uint64_t) p[3] << 32 ) |
+ ( (uint64_t) p[4] << 24 ) |
+ ( (uint64_t) p[5] << 16 ) |
+ ( (uint64_t) p[6] << 8 ) |
+ ( (uint64_t) p[7] );
+ p += 8;
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
- if( hs_buf->is_valid == 1 )
- {
- hs->buffering.total_bytes_buffered -= hs_buf->data_len;
- mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len );
- mbedtls_free( hs_buf->data );
- memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
- }
-}
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( (size_t)( end - p ) < 1 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ ssl->disable_datagram_packing = *p++;
#endif /* MBEDTLS_SSL_PROTO_DTLS */
-void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+ if( (size_t)( end - p ) < 8 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( handshake == NULL )
- return;
+ memcpy( ssl->cur_out_ctr, p, 8 );
+ p += 8;
-#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
- if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( (size_t)( end - p ) < 2 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ssl->mtu = ( p[0] << 8 ) | p[1];
+ p += 2;
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_ALPN)
{
- ssl->conf->f_async_cancel( ssl );
- handshake->async_in_progress = 0;
- }
-#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+ uint8_t alpn_len;
+ const char **cur;
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- mbedtls_md5_free( &handshake->fin_md5 );
- mbedtls_sha1_free( &handshake->fin_sha1 );
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA256_C)
- mbedtls_sha256_free( &handshake->fin_sha256 );
-#endif
-#if defined(MBEDTLS_SHA512_C)
- mbedtls_sha512_free( &handshake->fin_sha512 );
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+ if( (size_t)( end - p ) < 1 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-#if defined(MBEDTLS_DHM_C)
- mbedtls_dhm_free( &handshake->dhm_ctx );
-#endif
-#if defined(MBEDTLS_ECDH_C)
- mbedtls_ecdh_free( &handshake->ecdh_ctx );
-#endif
-#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
-#if defined(MBEDTLS_SSL_CLI_C)
- mbedtls_free( handshake->ecjpake_cache );
- handshake->ecjpake_cache = NULL;
- handshake->ecjpake_cache_len = 0;
-#endif
-#endif
+ alpn_len = *p++;
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- /* explicit void pointer cast for buggy MS compiler */
- mbedtls_free( (void *) handshake->curves );
-#endif
+ if( alpn_len != 0 && ssl->conf->alpn_list != NULL )
+ {
+ /* alpn_chosen should point to an item in the configured list */
+ for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
+ {
+ if( strlen( *cur ) == alpn_len &&
+ memcmp( p, cur, alpn_len ) == 0 )
+ {
+ ssl->alpn_chosen = *cur;
+ break;
+ }
+ }
+ }
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- if( handshake->psk != NULL )
- {
- mbedtls_platform_zeroize( handshake->psk, handshake->psk_len );
- mbedtls_free( handshake->psk );
+ /* can only happen on conf mismatch */
+ if( alpn_len != 0 && ssl->alpn_chosen == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ p += alpn_len;
}
-#endif
+#endif /* MBEDTLS_SSL_ALPN */
-#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
- defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
/*
- * Free only the linked list wrapper, not the keys themselves
- * since the belong to the SNI callback
+ * Forced fields from top-level ssl_context structure
+ *
+ * Most of them already set to the correct value by mbedtls_ssl_init() and
+ * mbedtls_ssl_reset(), so we only need to set the remaining ones.
*/
- if( handshake->sni_key_cert != NULL )
- {
- mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
+ ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER;
- while( cur != NULL )
- {
- next = cur->next;
- mbedtls_free( cur );
- cur = next;
- }
- }
-#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
+ ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
+ ssl->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx );
-#endif
+ /* Adjust pointers for header fields of outgoing records to
+ * the given transform, accounting for explicit IV and CID. */
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- mbedtls_free( handshake->verify_cookie );
- ssl_flight_free( handshake->flight );
- ssl_buffering_free( ssl );
+ ssl->in_epoch = 1;
#endif
- mbedtls_platform_zeroize( handshake,
- sizeof( mbedtls_ssl_handshake_params ) );
+ /* mbedtls_ssl_reset() leaves the handshake sub-structure allocated,
+ * which we don't want - otherwise we'd end up freeing the wrong transform
+ * by calling mbedtls_ssl_handshake_wrapup_free_hs_transform()
+ * inappropriately. */
+ if( ssl->handshake != NULL )
+ {
+ mbedtls_ssl_handshake_free( ssl );
+ mbedtls_free( ssl->handshake );
+ ssl->handshake = NULL;
+ }
+
+ /*
+ * Done - should have consumed entire buffer
+ */
+ if( p != end )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ return( 0 );
}
-void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
+/*
+ * Deserialize context: public wrapper for error cleaning
+ */
+int mbedtls_ssl_context_load( mbedtls_ssl_context *context,
+ const unsigned char *buf,
+ size_t len )
{
- if( session == NULL )
- return;
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( session->peer_cert != NULL )
- {
- mbedtls_x509_crt_free( session->peer_cert );
- mbedtls_free( session->peer_cert );
- }
-#endif
+ int ret = ssl_context_load( context, buf, len );
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
- mbedtls_free( session->ticket );
-#endif
+ if( ret != 0 )
+ mbedtls_ssl_free( context );
- mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) );
+ return( ret );
}
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
/*
* Free an SSL context
@@ -9238,14 +6801,28 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
if( ssl->out_buf != NULL )
{
- mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+
+ mbedtls_platform_zeroize( ssl->out_buf, out_buf_len );
mbedtls_free( ssl->out_buf );
+ ssl->out_buf = NULL;
}
if( ssl->in_buf != NULL )
{
- mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+
+ mbedtls_platform_zeroize( ssl->in_buf, in_buf_len );
mbedtls_free( ssl->in_buf );
+ ssl->in_buf = NULL;
}
#if defined(MBEDTLS_ZLIB_SUPPORT)
@@ -9313,10 +6890,12 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
memset( conf, 0, sizeof( mbedtls_ssl_config ) );
}
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
static int ssl_preset_default_hashes[] = {
#if defined(MBEDTLS_SHA512_C)
MBEDTLS_MD_SHA512,
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
MBEDTLS_MD_SHA384,
#endif
#if defined(MBEDTLS_SHA256_C)
@@ -9336,7 +6915,7 @@ static int ssl_preset_suiteb_ciphersuites[] = {
0
};
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
static int ssl_preset_suiteb_hashes[] = {
MBEDTLS_MD_SHA256,
MBEDTLS_MD_SHA384,
@@ -9363,7 +6942,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
int endpoint, int transport, int preset )
{
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#endif
/* Use the functions here so that they are covered in tests,
@@ -9465,7 +7044,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
conf->sig_hashes = ssl_preset_suiteb_hashes;
#endif
@@ -9504,7 +7083,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
conf->cert_profile = &mbedtls_x509_crt_profile_default;
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
conf->sig_hashes = ssl_preset_default_hashes;
#endif
@@ -9530,7 +7109,7 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
mbedtls_mpi_free( &conf->dhm_G );
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
if( conf->psk != NULL )
{
mbedtls_platform_zeroize( conf->psk, conf->psk_len );
@@ -9605,7 +7184,7 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/* Find an entry in a signature-hash set matching a given hash algorithm. */
mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
@@ -9653,7 +7232,7 @@ void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/*
* Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
@@ -9676,9 +7255,11 @@ mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash )
case MBEDTLS_SSL_HASH_SHA256:
return( MBEDTLS_MD_SHA256 );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
case MBEDTLS_SSL_HASH_SHA384:
return( MBEDTLS_MD_SHA384 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_SSL_HASH_SHA512:
return( MBEDTLS_MD_SHA512 );
#endif
@@ -9708,9 +7289,11 @@ unsigned char mbedtls_ssl_hash_from_md_alg( int md )
case MBEDTLS_MD_SHA256:
return( MBEDTLS_SSL_HASH_SHA256 );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
case MBEDTLS_MD_SHA384:
return( MBEDTLS_SSL_HASH_SHA384 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA512:
return( MBEDTLS_SSL_HASH_SHA512 );
#endif
@@ -9739,7 +7322,7 @@ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_i
}
#endif /* MBEDTLS_ECP_C */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Check if a hash proposed by the peer is in our list.
* Return 0 if we're willing to use it, -1 otherwise.
@@ -9758,7 +7341,7 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
return( -1 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
@@ -9851,59 +7434,6 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
-/*
- * Convert version numbers to/from wire format
- * and, for DTLS, to/from TLS equivalent.
- *
- * For TLS this is the identity.
- * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
- * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1)
- * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
- */
-void mbedtls_ssl_write_version( int major, int minor, int transport,
- unsigned char ver[2] )
-{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
- --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
-
- ver[0] = (unsigned char)( 255 - ( major - 2 ) );
- ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
- }
- else
-#else
- ((void) transport);
-#endif
- {
- ver[0] = (unsigned char) major;
- ver[1] = (unsigned char) minor;
- }
-}
-
-void mbedtls_ssl_read_version( int *major, int *minor, int transport,
- const unsigned char ver[2] )
-{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- *major = 255 - ver[0] + 2;
- *minor = 255 - ver[1] + 1;
-
- if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
- ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
- }
- else
-#else
- ((void) transport);
-#endif
- {
- *major = ver[0];
- *minor = ver[1];
- }
-}
-
int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
{
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -9923,7 +7453,7 @@ int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
break;
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
case MBEDTLS_SSL_HASH_SHA384:
ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
break;
@@ -10034,6 +7564,70 @@ exit:
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+ unsigned char *hash, size_t *hashlen,
+ unsigned char *data, size_t data_len,
+ mbedtls_md_type_t md_alg )
+{
+ psa_status_t status;
+ psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
+ psa_algorithm_t hash_alg = mbedtls_psa_translate_md( md_alg );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) );
+
+ if( ( status = psa_hash_setup( &hash_operation,
+ hash_alg ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_setup", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_update( &hash_operation, ssl->handshake->randbytes,
+ 64 ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_update( &hash_operation,
+ data, data_len ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_finish( &hash_operation, hash, PSA_HASH_MAX_SIZE,
+ hashlen ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_finish", status );
+ goto exit;
+ }
+
+exit:
+ if( status != PSA_SUCCESS )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+ switch( status )
+ {
+ case PSA_ERROR_NOT_SUPPORTED:
+ return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
+ case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
+ case PSA_ERROR_BUFFER_TOO_SMALL:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ case PSA_ERROR_INSUFFICIENT_MEMORY:
+ return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+ default:
+ return( MBEDTLS_ERR_MD_HW_ACCEL_FAILED );
+ }
+ }
+ return( 0 );
+}
+
+#else
+
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
unsigned char *hash, size_t *hashlen,
unsigned char *data, size_t data_len,
@@ -10044,6 +7638,8 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
*hashlen = mbedtls_md_get_size( md_info );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) );
+
mbedtls_md_init( &ctx );
/*
@@ -10088,6 +7684,8 @@ exit:
return( ret );
}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */
diff --git a/thirdparty/mbedtls/library/ssl_tls13_keys.c b/thirdparty/mbedtls/library/ssl_tls13_keys.c
new file mode 100644
index 0000000000..3de6f03fb8
--- /dev/null
+++ b/thirdparty/mbedtls/library/ssl_tls13_keys.c
@@ -0,0 +1,349 @@
+/*
+ * TLS 1.3 key schedule
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" ); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#include "mbedtls/hkdf.h"
+#include "mbedtls/ssl_internal.h"
+#include "ssl_tls13_keys.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
+ .name = string,
+
+struct mbedtls_ssl_tls1_3_labels_struct const mbedtls_ssl_tls1_3_labels =
+{
+ /* This seems to work in C, despite the string literal being one
+ * character too long due to the 0-termination. */
+ MBEDTLS_SSL_TLS1_3_LABEL_LIST
+};
+
+#undef MBEDTLS_SSL_TLS1_3_LABEL
+
+/*
+ * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule.
+ *
+ * The HkdfLabel is specified in RFC 8446 as follows:
+ *
+ * struct HkdfLabel {
+ * uint16 length; // Length of expanded key material
+ * opaque label<7..255>; // Always prefixed by "tls13 "
+ * opaque context<0..255>; // Usually a communication transcript hash
+ * };
+ *
+ * Parameters:
+ * - desired_length: Length of expanded key material
+ * Even though the standard allows expansion to up to
+ * 2**16 Bytes, TLS 1.3 never uses expansion to more than
+ * 255 Bytes, so we require `desired_length` to be at most
+ * 255. This allows us to save a few Bytes of code by
+ * hardcoding the writing of the high bytes.
+ * - (label, llen): label + label length, without "tls13 " prefix
+ * The label length MUST be less than or equal to
+ * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN
+ * It is the caller's responsibility to ensure this.
+ * All (label, label length) pairs used in TLS 1.3
+ * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN().
+ * - (ctx, clen): context + context length
+ * The context length MUST be less than or equal to
+ * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN
+ * It is the caller's responsibility to ensure this.
+ * - dst: Target buffer for HkdfLabel structure,
+ * This MUST be a writable buffer of size
+ * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes.
+ * - dlen: Pointer at which to store the actual length of
+ * the HkdfLabel structure on success.
+ */
+
+static const char tls1_3_label_prefix[6] = "tls13 ";
+
+#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( label_len, context_len ) \
+ ( 2 /* expansion length */ \
+ + 1 /* label length */ \
+ + label_len \
+ + 1 /* context length */ \
+ + context_len )
+
+#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \
+ SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \
+ sizeof(tls1_3_label_prefix) + \
+ MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \
+ MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN )
+
+static void ssl_tls1_3_hkdf_encode_label(
+ size_t desired_length,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ unsigned char *dst, size_t *dlen )
+{
+ size_t total_label_len =
+ sizeof(tls1_3_label_prefix) + llen;
+ size_t total_hkdf_lbl_len =
+ SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( total_label_len, clen );
+
+ unsigned char *p = dst;
+
+ /* Add the size of the expanded key material.
+ * We're hardcoding the high byte to 0 here assuming that we never use
+ * TLS 1.3 HKDF key expansion to more than 255 Bytes. */
+#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255
+#error "The implementation of ssl_tls1_3_hkdf_encode_label() is not fit for the \
+ value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN"
+#endif
+
+ *p++ = 0;
+ *p++ = MBEDTLS_BYTE_0( desired_length );
+
+ /* Add label incl. prefix */
+ *p++ = MBEDTLS_BYTE_0( total_label_len );
+ memcpy( p, tls1_3_label_prefix, sizeof(tls1_3_label_prefix) );
+ p += sizeof(tls1_3_label_prefix);
+ memcpy( p, label, llen );
+ p += llen;
+
+ /* Add context value */
+ *p++ = MBEDTLS_BYTE_0( clen );
+ if( clen != 0 )
+ memcpy( p, ctx, clen );
+
+ /* Return total length to the caller. */
+ *dlen = total_hkdf_lbl_len;
+}
+
+int mbedtls_ssl_tls1_3_hkdf_expand_label(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret, size_t slen,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ unsigned char *buf, size_t blen )
+{
+ const mbedtls_md_info_t *md;
+ unsigned char hkdf_label[ SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN ];
+ size_t hkdf_label_len;
+
+ if( llen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN )
+ {
+ /* Should never happen since this is an internal
+ * function, and we know statically which labels
+ * are allowed. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ if( clen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN )
+ {
+ /* Should not happen, as above. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ if( blen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN )
+ {
+ /* Should not happen, as above. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ md = mbedtls_md_info_from_type( hash_alg );
+ if( md == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ssl_tls1_3_hkdf_encode_label( blen,
+ label, llen,
+ ctx, clen,
+ hkdf_label,
+ &hkdf_label_len );
+
+ return( mbedtls_hkdf_expand( md,
+ secret, slen,
+ hkdf_label, hkdf_label_len,
+ buf, blen ) );
+}
+
+/*
+ * The traffic keying material is generated from the following inputs:
+ *
+ * - One secret value per sender.
+ * - A purpose value indicating the specific value being generated
+ * - The desired lengths of key and IV.
+ *
+ * The expansion itself is based on HKDF:
+ *
+ * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length )
+ * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length )
+ *
+ * [sender] denotes the sending side and the Secret value is provided
+ * by the function caller. Note that we generate server and client side
+ * keys in a single function call.
+ */
+int mbedtls_ssl_tls1_3_make_traffic_keys(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *client_secret,
+ const unsigned char *server_secret,
+ size_t slen, size_t key_len, size_t iv_len,
+ mbedtls_ssl_key_set *keys )
+{
+ int ret = 0;
+
+ ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ client_secret, slen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
+ NULL, 0,
+ keys->client_write_key, key_len );
+ if( ret != 0 )
+ return( ret );
+
+ ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ server_secret, slen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
+ NULL, 0,
+ keys->server_write_key, key_len );
+ if( ret != 0 )
+ return( ret );
+
+ ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ client_secret, slen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
+ NULL, 0,
+ keys->client_write_iv, iv_len );
+ if( ret != 0 )
+ return( ret );
+
+ ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ server_secret, slen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
+ NULL, 0,
+ keys->server_write_iv, iv_len );
+ if( ret != 0 )
+ return( ret );
+
+ keys->key_len = key_len;
+ keys->iv_len = iv_len;
+
+ return( 0 );
+}
+
+int mbedtls_ssl_tls1_3_derive_secret(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret, size_t slen,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ int ctx_hashed,
+ unsigned char *dstbuf, size_t buflen )
+{
+ int ret;
+ unsigned char hashed_context[ MBEDTLS_MD_MAX_SIZE ];
+
+ const mbedtls_md_info_t *md;
+ md = mbedtls_md_info_from_type( hash_alg );
+ if( md == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED )
+ {
+ ret = mbedtls_md( md, ctx, clen, hashed_context );
+ if( ret != 0 )
+ return( ret );
+ clen = mbedtls_md_get_size( md );
+ }
+ else
+ {
+ if( clen > sizeof(hashed_context) )
+ {
+ /* This should never happen since this function is internal
+ * and the code sets `ctx_hashed` correctly.
+ * Let's double-check nonetheless to not run at the risk
+ * of getting a stack overflow. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ memcpy( hashed_context, ctx, clen );
+ }
+
+ return( mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ secret, slen,
+ label, llen,
+ hashed_context, clen,
+ dstbuf, buflen ) );
+}
+
+int mbedtls_ssl_tls1_3_evolve_secret(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret_old,
+ const unsigned char *input, size_t input_len,
+ unsigned char *secret_new )
+{
+ int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ size_t hlen, ilen;
+ unsigned char tmp_secret[ MBEDTLS_MD_MAX_SIZE ] = { 0 };
+ unsigned char tmp_input [ MBEDTLS_MD_MAX_SIZE ] = { 0 };
+
+ const mbedtls_md_info_t *md;
+ md = mbedtls_md_info_from_type( hash_alg );
+ if( md == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ hlen = mbedtls_md_get_size( md );
+
+ /* For non-initial runs, call Derive-Secret( ., "derived", "")
+ * on the old secret. */
+ if( secret_old != NULL )
+ {
+ ret = mbedtls_ssl_tls1_3_derive_secret(
+ hash_alg,
+ secret_old, hlen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( derived ),
+ NULL, 0, /* context */
+ MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
+ tmp_secret, hlen );
+ if( ret != 0 )
+ goto cleanup;
+ }
+
+ if( input != NULL )
+ {
+ memcpy( tmp_input, input, input_len );
+ ilen = input_len;
+ }
+ else
+ {
+ ilen = hlen;
+ }
+
+ /* HKDF-Extract takes a salt and input key material.
+ * The salt is the old secret, and the input key material
+ * is the input secret (PSK / ECDHE). */
+ ret = mbedtls_hkdf_extract( md,
+ tmp_secret, hlen,
+ tmp_input, ilen,
+ secret_new );
+ if( ret != 0 )
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+
+ mbedtls_platform_zeroize( tmp_secret, sizeof(tmp_secret) );
+ mbedtls_platform_zeroize( tmp_input, sizeof(tmp_input) );
+ return( ret );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/thirdparty/mbedtls/library/ssl_tls13_keys.h b/thirdparty/mbedtls/library/ssl_tls13_keys.h
new file mode 100644
index 0000000000..7089049ce2
--- /dev/null
+++ b/thirdparty/mbedtls/library/ssl_tls13_keys.h
@@ -0,0 +1,274 @@
+/*
+ * TLS 1.3 key schedule
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" ); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#if !defined(MBEDTLS_SSL_TLS1_3_KEYS_H)
+#define MBEDTLS_SSL_TLS1_3_KEYS_H
+
+/* This requires MBEDTLS_SSL_TLS1_3_LABEL( idx, name, string ) to be defined at
+ * the point of use. See e.g. the definition of mbedtls_ssl_tls1_3_labels_union
+ * below. */
+#define MBEDTLS_SSL_TLS1_3_LABEL_LIST \
+ MBEDTLS_SSL_TLS1_3_LABEL( finished , "finished" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( resumption , "resumption" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( traffic_upd , "traffic upd" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( exporter , "exporter" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( key , "key" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( iv , "iv" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( c_hs_traffic, "c hs traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( c_ap_traffic, "c ap traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( c_e_traffic , "c e traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( s_hs_traffic, "s hs traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( s_ap_traffic, "s ap traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( s_e_traffic , "s e traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( e_exp_master, "e exp master" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( res_master , "res master" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( exp_master , "exp master" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( ext_binder , "ext binder" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( res_binder , "res binder" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( derived , "derived" )
+
+#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
+ const unsigned char name [ sizeof(string) - 1 ];
+
+union mbedtls_ssl_tls1_3_labels_union
+{
+ MBEDTLS_SSL_TLS1_3_LABEL_LIST
+};
+struct mbedtls_ssl_tls1_3_labels_struct
+{
+ MBEDTLS_SSL_TLS1_3_LABEL_LIST
+};
+#undef MBEDTLS_SSL_TLS1_3_LABEL
+
+extern const struct mbedtls_ssl_tls1_3_labels_struct mbedtls_ssl_tls1_3_labels;
+
+#define MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( LABEL ) \
+ mbedtls_ssl_tls1_3_labels.LABEL, \
+ sizeof(mbedtls_ssl_tls1_3_labels.LABEL)
+
+#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN \
+ sizeof( union mbedtls_ssl_tls1_3_labels_union )
+
+/* The maximum length of HKDF contexts used in the TLS 1.3 standard.
+ * Since contexts are always hashes of message transcripts, this can
+ * be approximated from above by the maximum hash size. */
+#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN \
+ MBEDTLS_MD_MAX_SIZE
+
+/* Maximum desired length for expanded key material generated
+ * by HKDF-Expand-Label.
+ *
+ * Warning: If this ever needs to be increased, the implementation
+ * ssl_tls1_3_hkdf_encode_label() in ssl_tls13_keys.c needs to be
+ * adjusted since it currently assumes that HKDF key expansion
+ * is never used with more than 255 Bytes of output. */
+#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN 255
+
+/**
+ * \brief The \c HKDF-Expand-Label function from
+ * the TLS 1.3 standard RFC 8446.
+ *
+ * <tt>
+ * HKDF-Expand-Label( Secret, Label, Context, Length ) =
+ * HKDF-Expand( Secret, HkdfLabel, Length )
+ * </tt>
+ *
+ * \param hash_alg The identifier for the hash algorithm to use.
+ * \param secret The \c Secret argument to \c HKDF-Expand-Label.
+ * This must be a readable buffer of length \p slen Bytes.
+ * \param slen The length of \p secret in Bytes.
+ * \param label The \c Label argument to \c HKDF-Expand-Label.
+ * This must be a readable buffer of length \p llen Bytes.
+ * \param llen The length of \p label in Bytes.
+ * \param ctx The \c Context argument to \c HKDF-Expand-Label.
+ * This must be a readable buffer of length \p clen Bytes.
+ * \param clen The length of \p context in Bytes.
+ * \param buf The destination buffer to hold the expanded secret.
+ * This must be a writable buffer of length \p blen Bytes.
+ * \param blen The desired size of the expanded secret in Bytes.
+ *
+ * \returns \c 0 on success.
+ * \return A negative error code on failure.
+ */
+
+int mbedtls_ssl_tls1_3_hkdf_expand_label(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret, size_t slen,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ unsigned char *buf, size_t blen );
+
+/**
+ * \brief This function is part of the TLS 1.3 key schedule.
+ * It extracts key and IV for the actual client/server traffic
+ * from the client/server traffic secrets.
+ *
+ * From RFC 8446:
+ *
+ * <tt>
+ * [sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length)
+ * [sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length)*
+ * </tt>
+ *
+ * \param hash_alg The identifier for the hash algorithm to be used
+ * for the HKDF-based expansion of the secret.
+ * \param client_secret The client traffic secret.
+ * This must be a readable buffer of size \p slen Bytes
+ * \param server_secret The server traffic secret.
+ * This must be a readable buffer of size \p slen Bytes
+ * \param slen Length of the secrets \p client_secret and
+ * \p server_secret in Bytes.
+ * \param key_len The desired length of the key to be extracted in Bytes.
+ * \param iv_len The desired length of the IV to be extracted in Bytes.
+ * \param keys The address of the structure holding the generated
+ * keys and IVs.
+ *
+ * \returns \c 0 on success.
+ * \returns A negative error code on failure.
+ */
+
+int mbedtls_ssl_tls1_3_make_traffic_keys(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *client_secret,
+ const unsigned char *server_secret,
+ size_t slen, size_t key_len, size_t iv_len,
+ mbedtls_ssl_key_set *keys );
+
+
+#define MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED 0
+#define MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED 1
+
+/**
+ * \brief The \c Derive-Secret function from the TLS 1.3 standard RFC 8446.
+ *
+ * <tt>
+ * Derive-Secret( Secret, Label, Messages ) =
+ * HKDF-Expand-Label( Secret, Label,
+ * Hash( Messages ),
+ * Hash.Length ) )
+ * </tt>
+ *
+ * \param hash_alg The identifier for the hash function used for the
+ * applications of HKDF.
+ * \param secret The \c Secret argument to the \c Derive-Secret function.
+ * This must be a readable buffer of length \p slen Bytes.
+ * \param slen The length of \p secret in Bytes.
+ * \param label The \c Label argument to the \c Derive-Secret function.
+ * This must be a readable buffer of length \p llen Bytes.
+ * \param llen The length of \p label in Bytes.
+ * \param ctx The hash of the \c Messages argument to the
+ * \c Derive-Secret function, or the \c Messages argument
+ * itself, depending on \p context_already_hashed.
+ * \param clen The length of \p hash.
+ * \param ctx_hashed This indicates whether the \p ctx contains the hash of
+ * the \c Messages argument in the application of the
+ * \c Derive-Secret function
+ * (value MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED), or whether
+ * it is the content of \c Messages itself, in which case
+ * the function takes care of the hashing
+ * (value MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED).
+ * \param dstbuf The target buffer to write the output of
+ * \c Derive-Secret to. This must be a writable buffer of
+ * size \p buflen Bytes.
+ * \param buflen The length of \p dstbuf in Bytes.
+ *
+ * \returns \c 0 on success.
+ * \returns A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_derive_secret(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret, size_t slen,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ int ctx_hashed,
+ unsigned char *dstbuf, size_t buflen );
+
+/**
+ * \brief Compute the next secret in the TLS 1.3 key schedule
+ *
+ * The TLS 1.3 key schedule proceeds as follows to compute
+ * the three main secrets during the handshake: The early
+ * secret for early data, the handshake secret for all
+ * other encrypted handshake messages, and the master
+ * secret for all application traffic.
+ *
+ * <tt>
+ * 0
+ * |
+ * v
+ * PSK -> HKDF-Extract = Early Secret
+ * |
+ * v
+ * Derive-Secret( ., "derived", "" )
+ * |
+ * v
+ * (EC)DHE -> HKDF-Extract = Handshake Secret
+ * |
+ * v
+ * Derive-Secret( ., "derived", "" )
+ * |
+ * v
+ * 0 -> HKDF-Extract = Master Secret
+ * </tt>
+ *
+ * Each of the three secrets in turn is the basis for further
+ * key derivations, such as the derivation of traffic keys and IVs;
+ * see e.g. mbedtls_ssl_tls1_3_make_traffic_keys().
+ *
+ * This function implements one step in this evolution of secrets:
+ *
+ * <tt>
+ * old_secret
+ * |
+ * v
+ * Derive-Secret( ., "derived", "" )
+ * |
+ * v
+ * input -> HKDF-Extract = new_secret
+ * </tt>
+ *
+ * \param hash_alg The identifier for the hash function used for the
+ * applications of HKDF.
+ * \param secret_old The address of the buffer holding the old secret
+ * on function entry. If not \c NULL, this must be a
+ * readable buffer whose size matches the output size
+ * of the hash function represented by \p hash_alg.
+ * If \c NULL, an all \c 0 array will be used instead.
+ * \param input The address of the buffer holding the additional
+ * input for the key derivation (e.g., the PSK or the
+ * ephemeral (EC)DH secret). If not \c NULL, this must be
+ * a readable buffer whose size \p input_len Bytes.
+ * If \c NULL, an all \c 0 array will be used instead.
+ * \param input_len The length of \p input in Bytes.
+ * \param secret_new The address of the buffer holding the new secret
+ * on function exit. This must be a writable buffer
+ * whose size matches the output size of the hash
+ * function represented by \p hash_alg.
+ * This may be the same as \p secret_old.
+ *
+ * \returns \c 0 on success.
+ * \returns A negative error code on failure.
+ */
+
+int mbedtls_ssl_tls1_3_evolve_secret(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret_old,
+ const unsigned char *input, size_t input_len,
+ unsigned char *secret_new );
+
+#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
diff --git a/thirdparty/mbedtls/library/threading.c b/thirdparty/mbedtls/library/threading.c
index 0dc5488c1a..2de117f52a 100644
--- a/thirdparty/mbedtls/library/threading.c
+++ b/thirdparty/mbedtls/library/threading.c
@@ -2,13 +2,7 @@
* Threading abstraction layer
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -52,11 +25,7 @@
#define _POSIX_C_SOURCE 200112L
#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_THREADING_C)
@@ -102,8 +71,8 @@ static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
* 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. */
+ * to distinguish more states of the mutex; see
+ * tests/src/threading_helpers for details. */
mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
}
diff --git a/thirdparty/mbedtls/library/timing.c b/thirdparty/mbedtls/library/timing.c
index 50a22165a6..eb41461320 100644
--- a/thirdparty/mbedtls/library/timing.c
+++ b/thirdparty/mbedtls/library/timing.c
@@ -2,13 +2,7 @@
* Portable interface to the CPU cycle counter
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
@@ -65,7 +34,7 @@
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
- !defined(__HAIKU__)
+ !defined(__HAIKU__) && !defined(__midipix__)
#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h"
#endif
diff --git a/thirdparty/mbedtls/library/version.c b/thirdparty/mbedtls/library/version.c
index 5733288f62..32a0d7d584 100644
--- a/thirdparty/mbedtls/library/version.c
+++ b/thirdparty/mbedtls/library/version.c
@@ -2,13 +2,7 @@
* Version information
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_VERSION_C)
diff --git a/thirdparty/mbedtls/library/version_features.c b/thirdparty/mbedtls/library/version_features.c
index 8c8e815e9d..40c95201bc 100644
--- a/thirdparty/mbedtls/library/version_features.c
+++ b/thirdparty/mbedtls/library/version_features.c
@@ -2,13 +2,7 @@
* Version feature information
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_VERSION_C)
@@ -56,7 +25,7 @@
#include <string.h>
-static const char *features[] = {
+static const char * const features[] = {
#if defined(MBEDTLS_VERSION_FEATURES)
#if defined(MBEDTLS_HAVE_ASM)
"MBEDTLS_HAVE_ASM",
@@ -97,6 +66,9 @@ static const char *features[] = {
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
"MBEDTLS_PLATFORM_SNPRINTF_ALT",
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+ "MBEDTLS_PLATFORM_VSNPRINTF_ALT",
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
"MBEDTLS_PLATFORM_NV_SEED_ALT",
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
@@ -253,6 +225,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
"MBEDTLS_ECP_INTERNAL_ALT",
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK)
+ "MBEDTLS_ECP_NO_FALLBACK",
+#endif /* MBEDTLS_ECP_NO_FALLBACK */
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
"MBEDTLS_ECP_RANDOMIZE_JAC_ALT",
#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */
@@ -277,12 +252,6 @@ static const char *features[] = {
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
"MBEDTLS_ECP_NORMALIZE_MXZ_ALT",
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
-#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
- "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN",
-#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */
-#if defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND)
- "MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND",
-#endif /* MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
"MBEDTLS_TEST_NULL_ENTROPY",
#endif /* MBEDTLS_TEST_NULL_ENTROPY */
@@ -298,6 +267,9 @@ static const char *features[] = {
#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
"MBEDTLS_CAMELLIA_SMALL_MEMORY",
#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+ "MBEDTLS_CHECK_RETURN_WARNING",
+#endif /* MBEDTLS_CHECK_RETURN_WARNING */
#if defined(MBEDTLS_CIPHER_MODE_CBC)
"MBEDTLS_CIPHER_MODE_CBC",
#endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -388,6 +360,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ECP_RESTARTABLE)
"MBEDTLS_ECP_RESTARTABLE",
#endif /* MBEDTLS_ECP_RESTARTABLE */
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+ "MBEDTLS_ECDH_LEGACY_CONTEXT",
+#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
"MBEDTLS_ECDSA_DETERMINISTIC",
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@@ -448,6 +423,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ENTROPY_NV_SEED)
"MBEDTLS_ENTROPY_NV_SEED",
#endif /* MBEDTLS_ENTROPY_NV_SEED */
+#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+ "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER",
+#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
#if defined(MBEDTLS_MEMORY_DEBUG)
"MBEDTLS_MEMORY_DEBUG",
#endif /* MBEDTLS_MEMORY_DEBUG */
@@ -463,6 +441,24 @@ static const char *features[] = {
#if defined(MBEDTLS_PKCS1_V21)
"MBEDTLS_PKCS1_V21",
#endif /* MBEDTLS_PKCS1_V21 */
+#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
+ "MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS",
+#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+ "MBEDTLS_PSA_CRYPTO_CLIENT",
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
+#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
+ "MBEDTLS_PSA_CRYPTO_DRIVERS",
+#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ "MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG",
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+#if defined(MBEDTLS_PSA_CRYPTO_SPM)
+ "MBEDTLS_PSA_CRYPTO_SPM",
+#endif /* MBEDTLS_PSA_CRYPTO_SPM */
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+ "MBEDTLS_PSA_INJECT_ENTROPY",
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
#if defined(MBEDTLS_RSA_NO_CRT)
"MBEDTLS_RSA_NO_CRT",
#endif /* MBEDTLS_RSA_NO_CRT */
@@ -472,12 +468,27 @@ static const char *features[] = {
#if defined(MBEDTLS_SHA256_SMALLER)
"MBEDTLS_SHA256_SMALLER",
#endif /* MBEDTLS_SHA256_SMALLER */
+#if defined(MBEDTLS_SHA512_SMALLER)
+ "MBEDTLS_SHA512_SMALLER",
+#endif /* MBEDTLS_SHA512_SMALLER */
+#if defined(MBEDTLS_SHA512_NO_SHA384)
+ "MBEDTLS_SHA512_NO_SHA384",
+#endif /* MBEDTLS_SHA512_NO_SHA384 */
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
"MBEDTLS_SSL_ALL_ALERT_MESSAGES",
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
+#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+ "MBEDTLS_SSL_RECORD_CHECKING",
+#endif /* MBEDTLS_SSL_RECORD_CHECKING */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ "MBEDTLS_SSL_DTLS_CONNECTION_ID",
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
"MBEDTLS_SSL_ASYNC_PRIVATE",
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+ "MBEDTLS_SSL_CONTEXT_SERIALIZATION",
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
#if defined(MBEDTLS_SSL_DEBUG_ALL)
"MBEDTLS_SSL_DEBUG_ALL",
#endif /* MBEDTLS_SSL_DEBUG_ALL */
@@ -490,6 +501,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
"MBEDTLS_SSL_FALLBACK_SCSV",
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ "MBEDTLS_SSL_KEEP_PEER_CERTIFICATE",
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
"MBEDTLS_SSL_HW_RECORD_ACCEL",
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
@@ -520,6 +534,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
"MBEDTLS_SSL_PROTO_TLS1_2",
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL",
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
"MBEDTLS_SSL_PROTO_DTLS",
#endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -532,6 +549,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
"MBEDTLS_SSL_DTLS_HELLO_VERIFY",
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ "MBEDTLS_SSL_DTLS_SRTP",
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
"MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE",
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */
@@ -553,6 +573,15 @@ 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_SSL_VARIABLE_BUFFER_LENGTH)
+ "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH",
+#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
+#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+ "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN",
+#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */
+#if defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND)
+ "MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND",
+#endif /* MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
#if defined(MBEDTLS_TEST_HOOKS)
"MBEDTLS_TEST_HOOKS",
#endif /* MBEDTLS_TEST_HOOKS */
@@ -562,6 +591,12 @@ static const char *features[] = {
#if defined(MBEDTLS_THREADING_PTHREAD)
"MBEDTLS_THREADING_PTHREAD",
#endif /* MBEDTLS_THREADING_PTHREAD */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ "MBEDTLS_USE_PSA_CRYPTO",
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+ "MBEDTLS_PSA_CRYPTO_CONFIG",
+#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
#if defined(MBEDTLS_VERSION_FEATURES)
"MBEDTLS_VERSION_FEATURES",
#endif /* MBEDTLS_VERSION_FEATURES */
@@ -571,6 +606,9 @@ static const char *features[] = {
#if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
"MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION",
#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ "MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK",
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
"MBEDTLS_X509_CHECK_KEY_USAGE",
#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
@@ -730,6 +768,18 @@ static const char *features[] = {
#if defined(MBEDTLS_POLY1305_C)
"MBEDTLS_POLY1305_C",
#endif /* MBEDTLS_POLY1305_C */
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+ "MBEDTLS_PSA_CRYPTO_C",
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+ "MBEDTLS_PSA_CRYPTO_SE_C",
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+ "MBEDTLS_PSA_CRYPTO_STORAGE_C",
+#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
+#if defined(MBEDTLS_PSA_ITS_FILE_C)
+ "MBEDTLS_PSA_ITS_FILE_C",
+#endif /* MBEDTLS_PSA_ITS_FILE_C */
#if defined(MBEDTLS_RIPEMD160_C)
"MBEDTLS_RIPEMD160_C",
#endif /* MBEDTLS_RIPEMD160_C */
@@ -802,7 +852,7 @@ static const char *features[] = {
int mbedtls_version_check_feature( const char *feature )
{
- const char **idx = features;
+ const char * const *idx = features;
if( *idx == NULL )
return( -2 );
diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c
index 0c820eca90..f21e9e6944 100644
--- a/thirdparty/mbedtls/library/x509.c
+++ b/thirdparty/mbedtls/library/x509.c
@@ -2,13 +2,7 @@
* X.509 common functions for parsing and verification
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -54,16 +27,13 @@
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_USE_C)
#include "mbedtls/x509.h"
#include "mbedtls/asn1.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include <stdio.h>
@@ -108,21 +78,21 @@
int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *serial )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) &&
**p != MBEDTLS_ASN1_INTEGER )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
serial->tag = *(*p)++;
if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL, ret ) );
serial->p = *p;
*p += serial->len;
@@ -139,10 +109,10 @@ int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *alg )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
return( 0 );
}
@@ -153,10 +123,10 @@ int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
return( 0 );
}
@@ -173,7 +143,7 @@ int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
*/
static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p;
const unsigned char *end;
mbedtls_x509_buf md_oid;
@@ -181,39 +151,39 @@ static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md
/* Make sure we got a SEQUENCE and setup bounds */
if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
- p = (unsigned char *) alg->p;
+ p = alg->p;
end = p + alg->len;
if( p >= end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
/* Parse md_oid */
md_oid.tag = *p;
if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
md_oid.p = p;
p += md_oid.len;
/* Get md_alg from md_oid */
if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
/* Make sure params is absent of NULL */
if( p == end )
return( 0 );
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -234,7 +204,7 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
int *salt_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p;
const unsigned char *end, *end2;
size_t len;
@@ -247,8 +217,8 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
/* Make sure params is a SEQUENCE and setup bounds */
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
p = (unsigned char *) params->p;
end = p + params->len;
@@ -269,14 +239,14 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
return( ret );
if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p == end )
return( 0 );
@@ -295,19 +265,19 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
/* Only MFG1 is recognised for now */
if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 )
- return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE +
- MBEDTLS_ERR_OID_NOT_FOUND );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE,
+ MBEDTLS_ERR_OID_NOT_FOUND ) );
/* Parse HashAlgorithm */
if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
return( ret );
if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p == end )
return( 0 );
@@ -321,14 +291,14 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
end2 = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p == end )
return( 0 );
@@ -344,21 +314,21 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
end2 = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
if( trailer_field != 1 )
return( MBEDTLS_ERR_X509_INVALID_ALG );
}
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -377,54 +347,54 @@ static int x509_get_attr_type_value( unsigned char **p,
const unsigned char *end,
mbedtls_x509_name *cur )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
mbedtls_x509_buf *oid;
mbedtls_x509_buf *val;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
end = *p + len;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
oid = &cur->oid;
oid->tag = **p;
if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
oid->p = *p;
*p += oid->len;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING &&
**p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
**p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
**p != MBEDTLS_ASN1_BIT_STRING )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
val = &cur->val;
val->tag = *(*p)++;
if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
val->p = *p;
*p += val->len;
if( *p != end )
{
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
cur->next = NULL;
@@ -458,7 +428,7 @@ static int x509_get_attr_type_value( unsigned char **p,
int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
mbedtls_x509_name *cur )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t set_len;
const unsigned char *end_set;
@@ -470,7 +440,7 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
*/
if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
end_set = *p + set_len;
@@ -564,7 +534,7 @@ static int x509_date_is_valid(const mbedtls_x509_time *t )
static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
mbedtls_x509_time *tm )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/*
* Minimum length is 10 or 12 depending on yearlen
@@ -629,13 +599,13 @@ static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
mbedtls_x509_time *tm )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len, year_len;
unsigned char tag;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
tag = **p;
@@ -644,32 +614,32 @@ int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
year_len = 4;
else
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
(*p)++;
ret = mbedtls_asn1_get_len( p, end, &len );
if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE, ret ) );
return x509_parse_time( p, len, year_len, tm );
}
int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
int tag_type;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SIGNATURE,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
tag_type = **p;
if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SIGNATURE, ret ) );
sig->tag = tag_type;
sig->len = len;
@@ -687,13 +657,13 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
void **sig_opts )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( *sig_opts != NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG, ret ) );
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
if( *pk_alg == MBEDTLS_PK_RSASSA_PSS )
@@ -735,7 +705,7 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50
int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *ext, int tag )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/* Extension structure use EXPLICIT tagging. That is, the actual
@@ -744,7 +714,7 @@ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
ret = mbedtls_asn1_get_tag( p, end, &ext->len,
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag );
if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
ext->p = *p;
@@ -755,11 +725,11 @@ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
*/
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( end != *p + len )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -770,7 +740,7 @@ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
*/
int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n;
unsigned char c, merge = 0;
const mbedtls_x509_name *name;
@@ -811,7 +781,7 @@ int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
break;
c = name->val.p[i];
- if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
+ if( c < 32 || c >= 127 )
s[i] = '?';
else s[i] = c;
}
@@ -832,7 +802,7 @@ int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
*/
int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n, nr;
char *p;
@@ -868,7 +838,7 @@ int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *s
mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
const void *sig_opts )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
char *p = buf;
size_t n = size;
const char *desc = NULL;
@@ -894,7 +864,7 @@ int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *s
ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
md_info ? mbedtls_md_get_name( md_info ) : "???",
mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
- pss_opts->expected_salt_len );
+ (unsigned int) pss_opts->expected_salt_len );
MBEDTLS_X509_SAFE_SNPRINTF;
}
#else
@@ -913,7 +883,7 @@ int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
{
char *p = buf;
size_t n = buf_size;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_snprintf( p, n, "%s key size", name );
MBEDTLS_X509_SAFE_SNPRINTF;
diff --git a/thirdparty/mbedtls/library/x509_create.c b/thirdparty/mbedtls/library/x509_create.c
index 0dbd679a93..056bbaa786 100644
--- a/thirdparty/mbedtls/library/x509_create.c
+++ b/thirdparty/mbedtls/library/x509_create.c
@@ -2,13 +2,7 @@
* X.509 base functions for creating certificates / CSRs
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,39 +15,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CREATE_C)
#include "mbedtls/x509.h"
#include "mbedtls/asn1write.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include <string.h>
@@ -266,7 +236,7 @@ int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid,
*/
static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data* cur_name)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
const char *oid = (const char*)cur_name->oid.p;
size_t oid_len = cur_name->oid.len;
@@ -299,7 +269,7 @@ static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn
int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *first )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_asn1_named_data *cur = first;
@@ -320,7 +290,7 @@ int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
unsigned char *sig, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if( *p < start || (size_t)( *p - start ) < size )
@@ -350,7 +320,7 @@ int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
static int x509_write_extension( unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *ext )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1,
@@ -388,7 +358,7 @@ static int x509_write_extension( unsigned char **p, unsigned char *start,
int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *first )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_asn1_named_data *cur_ext = first;
diff --git a/thirdparty/mbedtls/library/x509_crl.c b/thirdparty/mbedtls/library/x509_crl.c
index dba71fad58..ac4fc75de3 100644
--- a/thirdparty/mbedtls/library/x509_crl.c
+++ b/thirdparty/mbedtls/library/x509_crl.c
@@ -2,13 +2,7 @@
* X.509 Certidicate Revocation List (CRL) parsing
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -54,15 +27,12 @@
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CRL_PARSE_C)
#include "mbedtls/x509_crl.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
@@ -99,7 +69,7 @@ static int x509_crl_get_version( unsigned char **p,
const unsigned char *end,
int *ver )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
{
@@ -109,7 +79,7 @@ static int x509_crl_get_version( unsigned char **p,
return( 0 );
}
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION, ret ) );
}
return( 0 );
@@ -126,7 +96,7 @@ static int x509_get_crl_ext( unsigned char **p,
const unsigned char *end,
mbedtls_x509_buf *ext )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( *p == end )
return( 0 );
@@ -155,7 +125,7 @@ static int x509_get_crl_ext( unsigned char **p,
/* Get enclosing sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
end_ext_data = *p + len;
@@ -163,7 +133,7 @@ static int x509_get_crl_ext( unsigned char **p,
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
MBEDTLS_ASN1_OID ) ) != 0 )
{
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
}
*p += len;
@@ -172,29 +142,29 @@ static int x509_get_crl_ext( unsigned char **p,
&is_critical ) ) != 0 &&
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
{
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
}
/* Data should be octet string type */
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
/* Ignore data so far and just check its length */
*p += len;
if( *p != end_ext_data )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/* Abort on (unsupported) critical extensions */
if( is_critical )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
}
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -206,7 +176,7 @@ static int x509_get_crl_entry_ext( unsigned char **p,
const unsigned char *end,
mbedtls_x509_buf *ext )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
/* OPTIONAL */
@@ -228,27 +198,27 @@ static int x509_get_crl_entry_ext( unsigned char **p,
ext->p = NULL;
return( 0 );
}
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
}
end = *p + ext->len;
if( end != *p + ext->len )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
while( *p < end )
{
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
*p += len;
}
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -260,7 +230,7 @@ static int x509_get_entries( unsigned char **p,
const unsigned char *end,
mbedtls_x509_crl_entry *entry )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t entry_len;
mbedtls_x509_crl_entry *cur_entry = entry;
@@ -325,7 +295,7 @@ static int x509_get_entries( unsigned char **p,
int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
const unsigned char *buf, size_t buflen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
unsigned char *p = NULL, *end = NULL;
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
@@ -394,8 +364,8 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
if( len != (size_t) ( end - p ) )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
/*
@@ -407,7 +377,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
end = p + len;
@@ -451,7 +421,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
@@ -474,10 +444,10 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 )
{
- if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) &&
- ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA ) )
+ if( ret != ( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) &&
+ ret != ( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ) )
{
mbedtls_x509_crl_free( crl );
return( ret );
@@ -516,8 +486,8 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
if( p != end )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
end = crl->raw.p + crl->raw.len;
@@ -551,8 +521,8 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
if( p != end )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
return( 0 );
@@ -564,8 +534,8 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen )
{
#if defined(MBEDTLS_PEM_PARSE_C)
- int ret;
- size_t use_len;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t use_len = 0;
mbedtls_pem_context pem;
int is_pem = 0;
@@ -628,7 +598,7 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s
*/
int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -655,7 +625,7 @@ int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
const mbedtls_x509_crl *crl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
char *p;
const mbedtls_x509_crl_entry *entry;
diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c
index 52f6de8fc0..60312bf2f5 100644
--- a/thirdparty/mbedtls/library/x509_crt.c
+++ b/thirdparty/mbedtls/library/x509_crt.c
@@ -2,13 +2,7 @@
* X.509 certificate parsing and verification
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -56,15 +29,12 @@
* [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/x509_crt.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
@@ -74,6 +44,11 @@
#include "mbedtls/pem.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -133,10 +108,6 @@ typedef struct {
* concerns. */
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
{
-#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
- /* Allow SHA-1 (weak, but still safe in controlled environments) */
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
-#endif
/* Only SHA-2 hashes */
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
@@ -409,6 +380,10 @@ static void x509_crt_verify_chain_reset(
}
ver_chain->len = 0;
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ ver_chain->trust_ca_cb_result = NULL;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
}
/*
@@ -418,7 +393,7 @@ static int x509_get_version( unsigned char **p,
const unsigned char *end,
int *ver )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
@@ -430,17 +405,17 @@ static int x509_get_version( unsigned char **p,
return( 0 );
}
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
end = *p + len;
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION, ret ) );
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_VERSION +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -455,12 +430,12 @@ static int x509_get_dates( unsigned char **p,
mbedtls_x509_time *from,
mbedtls_x509_time *to )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE, ret ) );
end = *p + len;
@@ -471,8 +446,8 @@ static int x509_get_dates( unsigned char **p,
return( ret );
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -484,7 +459,7 @@ static int x509_get_uid( unsigned char **p,
const unsigned char *end,
mbedtls_x509_buf *uid, int n )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( *p == end )
return( 0 );
@@ -497,7 +472,7 @@ static int x509_get_uid( unsigned char **p,
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
return( 0 );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
uid->p = *p;
@@ -511,7 +486,7 @@ static int x509_get_basic_constraints( unsigned char **p,
int *ca_istrue,
int *max_pathlen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/*
@@ -524,7 +499,7 @@ static int x509_get_basic_constraints( unsigned char **p,
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( *p == end )
return( 0 );
@@ -535,7 +510,7 @@ static int x509_get_basic_constraints( unsigned char **p,
ret = mbedtls_asn1_get_int( p, end, ca_istrue );
if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( *ca_istrue != 0 )
*ca_istrue = 1;
@@ -545,17 +520,17 @@ static int x509_get_basic_constraints( unsigned char **p,
return( 0 );
if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer
* overflow, which is an undefined behavior. */
if( *max_pathlen == INT_MAX )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_INVALID_LENGTH ) );
(*max_pathlen)++;
@@ -566,15 +541,15 @@ static int x509_get_ns_cert_type( unsigned char **p,
const unsigned char *end,
unsigned char *ns_cert_type)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_bitstring bs = { 0, 0, NULL };
if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( bs.len != 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_INVALID_LENGTH ) );
/* Get actual bitstring */
*ns_cert_type = *bs.p;
@@ -585,16 +560,16 @@ static int x509_get_key_usage( unsigned char **p,
const unsigned char *end,
unsigned int *key_usage)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_x509_bitstring bs = { 0, 0, NULL };
if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( bs.len < 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_INVALID_LENGTH ) );
/* Get actual bitstring */
*key_usage = 0;
@@ -615,15 +590,15 @@ static int x509_get_ext_key_usage( unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *ext_key_usage)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
/* Sequence length must be >= 1 */
if( ext_key_usage->buf.p == NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_INVALID_LENGTH ) );
return( 0 );
}
@@ -652,13 +627,14 @@ static int x509_get_ext_key_usage( unsigned char **p,
* nameAssigner [0] DirectoryString OPTIONAL,
* partyName [1] DirectoryString }
*
- * NOTE: we only parse and use dNSName at this point.
+ * NOTE: we list all types, but only use dNSName and otherName
+ * of type HwModuleName, as defined in RFC 4108, at this point.
*/
static int x509_get_subject_alt_name( unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *subject_alt_name )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len, tag_len;
mbedtls_asn1_buf *buf;
unsigned char tag;
@@ -667,35 +643,51 @@ static int x509_get_subject_alt_name( unsigned char **p,
/* Get main sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( *p + len != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
while( *p < end )
{
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ mbedtls_x509_subject_alternative_name dummy_san_buf;
+ memset( &dummy_san_buf, 0, sizeof( dummy_san_buf ) );
tag = **p;
(*p)++;
if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) !=
MBEDTLS_ASN1_CONTEXT_SPECIFIC )
{
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
}
- /* Skip everything but DNS name */
- if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
+ /*
+ * Check that the SAN is structured correctly.
+ */
+ ret = mbedtls_x509_parse_subject_alt_name( &(cur->buf), &dummy_san_buf );
+ /*
+ * In case the extension is malformed, return an error,
+ * and clear the allocated sequences.
+ */
+ if( ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
{
- *p += tag_len;
- continue;
+ mbedtls_x509_sequence *seq_cur = subject_alt_name->next;
+ mbedtls_x509_sequence *seq_prv;
+ while( seq_cur != NULL )
+ {
+ seq_prv = seq_cur;
+ seq_cur = seq_cur->next;
+ mbedtls_platform_zeroize( seq_prv,
+ sizeof( mbedtls_x509_sequence ) );
+ mbedtls_free( seq_prv );
+ }
+ subject_alt_name->next = NULL;
+ return( ret );
}
/* Allocate and assign next pointer */
@@ -707,8 +699,8 @@ static int x509_get_subject_alt_name( unsigned char **p,
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
if( cur->next == NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_ALLOC_FAILED ) );
cur = cur->next;
}
@@ -724,23 +716,187 @@ static int x509_get_subject_alt_name( unsigned char **p,
cur->next = NULL;
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
/*
+ * id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+ *
+ * anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
+ *
+ * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+ *
+ * PolicyInformation ::= SEQUENCE {
+ * policyIdentifier CertPolicyId,
+ * policyQualifiers SEQUENCE SIZE (1..MAX) OF
+ * PolicyQualifierInfo OPTIONAL }
+ *
+ * CertPolicyId ::= OBJECT IDENTIFIER
+ *
+ * PolicyQualifierInfo ::= SEQUENCE {
+ * policyQualifierId PolicyQualifierId,
+ * qualifier ANY DEFINED BY policyQualifierId }
+ *
+ * -- policyQualifierIds for Internet policy qualifiers
+ *
+ * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+ * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+ * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+ *
+ * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+ *
+ * Qualifier ::= CHOICE {
+ * cPSuri CPSuri,
+ * userNotice UserNotice }
+ *
+ * CPSuri ::= IA5String
+ *
+ * UserNotice ::= SEQUENCE {
+ * noticeRef NoticeReference OPTIONAL,
+ * explicitText DisplayText OPTIONAL }
+ *
+ * NoticeReference ::= SEQUENCE {
+ * organization DisplayText,
+ * noticeNumbers SEQUENCE OF INTEGER }
+ *
+ * DisplayText ::= CHOICE {
+ * ia5String IA5String (SIZE (1..200)),
+ * visibleString VisibleString (SIZE (1..200)),
+ * bmpString BMPString (SIZE (1..200)),
+ * utf8String UTF8String (SIZE (1..200)) }
+ *
+ * NOTE: we only parse and use anyPolicy without qualifiers at this point
+ * as defined in RFC 5280.
+ */
+static int x509_get_certificate_policies( unsigned char **p,
+ const unsigned char *end,
+ mbedtls_x509_sequence *certificate_policies )
+{
+ int ret, parse_ret = 0;
+ size_t len;
+ mbedtls_asn1_buf *buf;
+ mbedtls_asn1_sequence *cur = certificate_policies;
+
+ /* Get main sequence tag */
+ ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
+ if( ret != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ if( *p + len != end )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+
+ /*
+ * Cannot be an empty sequence.
+ */
+ if( len == 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+
+ while( *p < end )
+ {
+ mbedtls_x509_buf policy_oid;
+ const unsigned char *policy_end;
+
+ /*
+ * Get the policy sequence
+ */
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ policy_end = *p + len;
+
+ if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
+ MBEDTLS_ASN1_OID ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ policy_oid.tag = MBEDTLS_ASN1_OID;
+ policy_oid.len = len;
+ policy_oid.p = *p;
+
+ /*
+ * Only AnyPolicy is currently supported when enforcing policy.
+ */
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_POLICY, &policy_oid ) != 0 )
+ {
+ /*
+ * Set the parsing return code but continue parsing, in case this
+ * extension is critical and MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ * is configured.
+ */
+ parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+ }
+
+ /* Allocate and assign next pointer */
+ if( cur->buf.p != NULL )
+ {
+ if( cur->next != NULL )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
+
+ cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
+
+ if( cur->next == NULL )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_ALLOC_FAILED ) );
+
+ cur = cur->next;
+ }
+
+ buf = &( cur->buf );
+ buf->tag = policy_oid.tag;
+ buf->p = policy_oid.p;
+ buf->len = policy_oid.len;
+
+ *p += len;
+
+ /*
+ * If there is an optional qualifier, then *p < policy_end
+ * Check the Qualifier len to verify it doesn't exceed policy_end.
+ */
+ if( *p < policy_end )
+ {
+ if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+ /*
+ * Skip the optional policy qualifiers.
+ */
+ *p += len;
+ }
+
+ if( *p != policy_end )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+ }
+
+ /* Set final sequence entry's next pointer to NULL */
+ cur->next = NULL;
+
+ if( *p != end )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+
+ return( parse_ret );
+}
+
+/*
* X.509 v3 extensions
*
*/
static int x509_get_crt_ext( unsigned char **p,
const unsigned char *end,
- mbedtls_x509_crt *crt )
+ mbedtls_x509_crt *crt,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
- unsigned char *end_ext_data, *end_ext_octet;
+ unsigned char *end_ext_data, *start_ext_octet, *end_ext_octet;
if( *p == end )
return( 0 );
@@ -763,14 +919,14 @@ static int x509_get_crt_ext( unsigned char **p,
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
end_ext_data = *p + len;
/* Get extension ID */
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len,
MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
extn_oid.tag = MBEDTLS_ASN1_OID;
extn_oid.p = *p;
@@ -779,18 +935,19 @@ static int x509_get_crt_ext( unsigned char **p,
/* Get optional critical */
if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
/* Data should be octet string type */
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+ start_ext_octet = *p;
end_ext_octet = *p + len;
if( end_ext_octet != end_ext_data )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/*
* Detect supported extensions
@@ -799,6 +956,16 @@ static int x509_get_crt_ext( unsigned char **p,
if( ret != 0 )
{
+ /* Give the callback (if any) a chance to handle the extension */
+ if( cb != NULL )
+ {
+ ret = cb( p_ctx, crt, &extn_oid, is_critical, *p, end_ext_octet );
+ if( ret != 0 && is_critical )
+ return( ret );
+ *p = end_ext_octet;
+ continue;
+ }
+
/* No parser found, skip extension */
*p = end_ext_octet;
@@ -806,8 +973,8 @@ static int x509_get_crt_ext( unsigned char **p,
if( is_critical )
{
/* Data is marked as critical: fail */
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
}
#endif
continue;
@@ -856,14 +1023,52 @@ static int x509_get_crt_ext( unsigned char **p,
return( ret );
break;
+ case MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES:
+ /* Parse certificate policies type */
+ if( ( ret = x509_get_certificate_policies( p, end_ext_octet,
+ &crt->certificate_policies ) ) != 0 )
+ {
+ /* Give the callback (if any) a chance to handle the extension
+ * if it contains unsupported policies */
+ if( ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE && cb != NULL &&
+ cb( p_ctx, crt, &extn_oid, is_critical,
+ start_ext_octet, end_ext_octet ) == 0 )
+ break;
+
+#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
+ if( is_critical )
+ return( ret );
+ else
+#endif
+ /*
+ * If MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE is returned, then we
+ * cannot interpret or enforce the policy. However, it is up to
+ * the user to choose how to enforce the policies,
+ * unless the extension is critical.
+ */
+ if( ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
+ return( ret );
+ }
+ break;
+
default:
- return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ /*
+ * If this is a non-critical extension, which the oid layer
+ * supports, but there isn't an x509 parser for it,
+ * skip the extension.
+ */
+#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
+ if( is_critical )
+ return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ else
+#endif
+ *p = end_ext_octet;
}
}
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -871,10 +1076,14 @@ static int x509_get_crt_ext( unsigned char **p,
/*
* Parse and fill a single X.509 certificate in DER format
*/
-static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
- size_t buflen )
+static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
unsigned char *p, *end, *crt_end;
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
@@ -889,7 +1098,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( crt == NULL || buf == NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- // Use the original buffer until we figure out actual length
+ /* Use the original buffer until we figure out actual length. */
p = (unsigned char*) buf;
len = buflen;
end = p + len;
@@ -907,25 +1116,26 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
return( MBEDTLS_ERR_X509_INVALID_FORMAT );
}
- if( len > (size_t) ( end - p ) )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- crt_end = p + len;
-
- // Create and populate a new buffer for the raw field
+ end = crt_end = p + len;
crt->raw.len = crt_end - buf;
- crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
- if( p == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+ if( make_copy != 0 )
+ {
+ /* Create and populate a new buffer for the raw field. */
+ crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
+ if( crt->raw.p == NULL )
+ return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- memcpy( p, buf, crt->raw.len );
+ memcpy( crt->raw.p, buf, crt->raw.len );
+ crt->own_buffer = 1;
- // Direct pointers to the new buffer
- p += crt->raw.len - len;
- end = crt_end = p + len;
+ p += crt->raw.len - len;
+ end = crt_end = p + len;
+ }
+ else
+ {
+ crt->raw.p = (unsigned char*) buf;
+ crt->own_buffer = 0;
+ }
/*
* TBSCertificate ::= SEQUENCE {
@@ -936,7 +1146,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
end = p + len;
@@ -983,7 +1193,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
@@ -1016,7 +1226,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
@@ -1030,11 +1240,13 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
/*
* SubjectPublicKeyInfo
*/
+ crt->pk_raw.p = p;
if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
return( ret );
}
+ crt->pk_raw.len = p - crt->pk_raw.p;
/*
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
@@ -1068,7 +1280,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( crt->version == 3 )
#endif
{
- ret = x509_get_crt_ext( &p, end, crt );
+ ret = x509_get_crt_ext( &p, end, crt, cb, p_ctx );
if( ret != 0 )
{
mbedtls_x509_crt_free( crt );
@@ -1079,8 +1291,8 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( p != end )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
end = crt_end;
@@ -1118,8 +1330,8 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( p != end )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
return( 0 );
@@ -1129,10 +1341,14 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
* Parse one X.509 certificate in DER format from a buffer and add them to a
* chained list
*/
-int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
- size_t buflen )
+static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_crt *crt = chain, *prev = NULL;
/*
@@ -1162,7 +1378,8 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu
crt = crt->next;
}
- if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
+ ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy, cb, p_ctx );
+ if( ret != 0 )
{
if( prev )
prev->next = NULL;
@@ -1176,11 +1393,37 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu
return( 0 );
}
+int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
+{
+ return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0, NULL, NULL ) );
+}
+
+int mbedtls_x509_crt_parse_der_with_ext_cb( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx )
+{
+ return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, make_copy, cb, p_ctx ) );
+}
+
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
+{
+ return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1, NULL, NULL ) );
+}
+
/*
* Parse one or more PEM certificates from a buffer and add them to the chained
* list
*/
-int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
+int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
{
#if defined(MBEDTLS_PEM_PARSE_C)
int success = 0, first_error = 0, total_failed = 0;
@@ -1213,7 +1456,7 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s
#if defined(MBEDTLS_PEM_PARSE_C)
if( buf_format == MBEDTLS_X509_FORMAT_PEM )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_pem_context pem;
/* 1 rather than 0 since the terminating NULL byte is counted in */
@@ -1297,7 +1540,7 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s
*/
int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -1409,6 +1652,8 @@ cleanup:
}
#endif /* MBEDTLS_THREADING_C */
+ memset( &sb, 0, sizeof( sb ) );
+
while( ( entry = readdir( dir ) ) != NULL )
{
snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name,
@@ -1451,32 +1696,201 @@ cleanup:
}
#endif /* MBEDTLS_FS_IO */
+/*
+ * OtherName ::= SEQUENCE {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * HardwareModuleName ::= SEQUENCE {
+ * hwType OBJECT IDENTIFIER,
+ * hwSerialNum OCTET STRING }
+ *
+ * NOTE: we currently only parse and use otherName of type HwModuleName,
+ * as defined in RFC 4108.
+ */
+static int x509_get_other_name( const mbedtls_x509_buf *subject_alt_name,
+ mbedtls_x509_san_other_name *other_name )
+{
+ int ret = 0;
+ size_t len;
+ unsigned char *p = subject_alt_name->p;
+ const unsigned char *end = p + subject_alt_name->len;
+ mbedtls_x509_buf cur_oid;
+
+ if( ( subject_alt_name->tag &
+ ( MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK ) ) !=
+ ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME ) )
+ {
+ /*
+ * The given subject alternative name is not of type "othername".
+ */
+ return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+ }
+
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+ MBEDTLS_ASN1_OID ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ cur_oid.tag = MBEDTLS_ASN1_OID;
+ cur_oid.p = p;
+ cur_oid.len = len;
+
+ /*
+ * Only HwModuleName is currently supported.
+ */
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid ) != 0 )
+ {
+ return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ }
+
+ if( p + len >= end )
+ {
+ mbedtls_platform_zeroize( other_name, sizeof( *other_name ) );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+ }
+ p += len;
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OID ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
+ other_name->value.hardware_module_name.oid.p = p;
+ other_name->value.hardware_module_name.oid.len = len;
+
+ if( p + len >= end )
+ {
+ mbedtls_platform_zeroize( other_name, sizeof( *other_name ) );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+ }
+ p += len;
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+ MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
+ other_name->value.hardware_module_name.val.p = p;
+ other_name->value.hardware_module_name.val.len = len;
+ p += len;
+ if( p != end )
+ {
+ mbedtls_platform_zeroize( other_name,
+ sizeof( *other_name ) );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+ }
+ return( 0 );
+}
+
static int x509_info_subject_alt_name( char **buf, size_t *size,
- const mbedtls_x509_sequence *subject_alt_name )
+ const mbedtls_x509_sequence
+ *subject_alt_name,
+ const char *prefix )
{
- size_t i;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n = *size;
char *p = *buf;
const mbedtls_x509_sequence *cur = subject_alt_name;
- const char *sep = "";
- size_t sep_len = 0;
+ mbedtls_x509_subject_alternative_name san;
+ int parse_ret;
while( cur != NULL )
{
- if( cur->buf.len + sep_len >= n )
+ memset( &san, 0, sizeof( san ) );
+ parse_ret = mbedtls_x509_parse_subject_alt_name( &cur->buf, &san );
+ if( parse_ret != 0 )
{
- *p = '\0';
- return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+ if( parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s <unsupported>", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ }
+ else
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s <malformed>", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ }
+ cur = cur->next;
+ continue;
}
- n -= cur->buf.len + sep_len;
- for( i = 0; i < sep_len; i++ )
- *p++ = sep[i];
- for( i = 0; i < cur->buf.len; i++ )
- *p++ = cur->buf.p[i];
+ switch( san.type )
+ {
+ /*
+ * otherName
+ */
+ case MBEDTLS_X509_SAN_OTHER_NAME:
+ {
+ mbedtls_x509_san_other_name *other_name = &san.san.other_name;
+
+ ret = mbedtls_snprintf( p, n, "\n%s otherName :", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
- sep = ", ";
- sep_len = 2;
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME,
+ &other_name->value.hardware_module_name.oid ) != 0 )
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s hardware module name :", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ ret = mbedtls_snprintf( p, n, "\n%s hardware type : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ ret = mbedtls_oid_get_numeric_string( p, n, &other_name->value.hardware_module_name.oid );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ ret = mbedtls_snprintf( p, n, "\n%s hardware serial number : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ if( other_name->value.hardware_module_name.val.len >= n )
+ {
+ *p = '\0';
+ return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+ }
+
+ memcpy( p, other_name->value.hardware_module_name.val.p,
+ other_name->value.hardware_module_name.val.len );
+ p += other_name->value.hardware_module_name.val.len;
+
+ n -= other_name->value.hardware_module_name.val.len;
+
+ }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
+ }
+ break;
+
+ /*
+ * dNSName
+ */
+ case MBEDTLS_X509_SAN_DNS_NAME:
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s dNSName : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ if( san.san.unstructured_name.len >= n )
+ {
+ *p = '\0';
+ return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+ }
+
+ memcpy( p, san.san.unstructured_name.p, san.san.unstructured_name.len );
+ p += san.san.unstructured_name.len;
+ n -= san.san.unstructured_name.len;
+ }
+ break;
+
+ /*
+ * Type not supported, skip item.
+ */
+ default:
+ ret = mbedtls_snprintf( p, n, "\n%s <unsupported>", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ break;
+ }
cur = cur->next;
}
@@ -1489,6 +1903,56 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
return( 0 );
}
+int mbedtls_x509_parse_subject_alt_name( const mbedtls_x509_buf *san_buf,
+ mbedtls_x509_subject_alternative_name *san )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ switch( san_buf->tag &
+ ( MBEDTLS_ASN1_TAG_CLASS_MASK |
+ MBEDTLS_ASN1_TAG_VALUE_MASK ) )
+ {
+ /*
+ * otherName
+ */
+ case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME ):
+ {
+ mbedtls_x509_san_other_name other_name;
+
+ ret = x509_get_other_name( san_buf, &other_name );
+ if( ret != 0 )
+ return( ret );
+
+ memset( san, 0, sizeof( mbedtls_x509_subject_alternative_name ) );
+ san->type = MBEDTLS_X509_SAN_OTHER_NAME;
+ memcpy( &san->san.other_name,
+ &other_name, sizeof( other_name ) );
+
+ }
+ break;
+
+ /*
+ * dNSName
+ */
+ case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME ):
+ {
+ memset( san, 0, sizeof( mbedtls_x509_subject_alternative_name ) );
+ san->type = MBEDTLS_X509_SAN_DNS_NAME;
+
+ memcpy( &san->san.unstructured_name,
+ san_buf, sizeof( *san_buf ) );
+
+ }
+ break;
+
+ /*
+ * Type not supported
+ */
+ default:
+ return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ }
+ return( 0 );
+}
+
#define PRINT_ITEM(i) \
{ \
ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
@@ -1503,7 +1967,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
static int x509_info_cert_type( char **buf, size_t *size,
unsigned char ns_cert_type )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n = *size;
char *p = *buf;
const char *sep = "";
@@ -1530,7 +1994,7 @@ static int x509_info_cert_type( char **buf, size_t *size,
static int x509_info_key_usage( char **buf, size_t *size,
unsigned int key_usage )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n = *size;
char *p = *buf;
const char *sep = "";
@@ -1554,7 +2018,7 @@ static int x509_info_key_usage( char **buf, size_t *size,
static int x509_info_ext_key_usage( char **buf, size_t *size,
const mbedtls_x509_sequence *extended_key_usage )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const char *desc;
size_t n = *size;
char *p = *buf;
@@ -1580,6 +2044,35 @@ static int x509_info_ext_key_usage( char **buf, size_t *size,
return( 0 );
}
+static int x509_info_cert_policies( char **buf, size_t *size,
+ const mbedtls_x509_sequence *certificate_policies )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const char *desc;
+ size_t n = *size;
+ char *p = *buf;
+ const mbedtls_x509_sequence *cur = certificate_policies;
+ const char *sep = "";
+
+ while( cur != NULL )
+ {
+ if( mbedtls_oid_get_certificate_policies( &cur->buf, &desc ) != 0 )
+ desc = "???";
+
+ ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ sep = ", ";
+
+ cur = cur->next;
+ }
+
+ *size = n;
+ *buf = p;
+
+ return( 0 );
+}
+
/*
* Return an informational string about the certificate.
*/
@@ -1588,7 +2081,7 @@ static int x509_info_ext_key_usage( char **buf, size_t *size,
int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
const mbedtls_x509_crt *crt )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
char *p;
char key_size_str[BEFORE_COLON];
@@ -1675,11 +2168,12 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
{
- ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix );
+ ret = mbedtls_snprintf( p, n, "\n%ssubject alt name :", prefix );
MBEDTLS_X509_SAFE_SNPRINTF;
if( ( ret = x509_info_subject_alt_name( &p, &n,
- &crt->subject_alt_names ) ) != 0 )
+ &crt->subject_alt_names,
+ prefix ) ) != 0 )
return( ret );
}
@@ -1711,6 +2205,16 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
return( ret );
}
+ if( crt->ext_types & MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES )
+ {
+ ret = mbedtls_snprintf( p, n, "\n%scertificate policies : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ if( ( ret = x509_info_cert_policies( &p, &n,
+ &crt->certificate_policies ) ) != 0 )
+ return( ret );
+ }
+
ret = mbedtls_snprintf( p, n, "\n" );
MBEDTLS_X509_SAFE_SNPRINTF;
@@ -1749,7 +2253,7 @@ static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
uint32_t flags )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const struct x509_crt_verify_string *cur;
char *p = buf;
size_t n = size;
@@ -1949,16 +2453,35 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child,
mbedtls_x509_crt *parent,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
- const mbedtls_md_info_t *md_info;
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
-
+ size_t hash_len;
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
+ const mbedtls_md_info_t *md_info;
md_info = mbedtls_md_info_from_type( child->sig_md );
+ hash_len = mbedtls_md_get_size( md_info );
+
+ /* Note: hash errors can happen only after an internal error */
if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 )
+ return( -1 );
+#else
+ psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
+ psa_algorithm_t hash_alg = mbedtls_psa_translate_md( child->sig_md );
+
+ if( psa_hash_setup( &hash_operation, hash_alg ) != PSA_SUCCESS )
+ return( -1 );
+
+ if( psa_hash_update( &hash_operation, child->tbs.p, child->tbs.len )
+ != PSA_SUCCESS )
{
- /* Note: this can't happen except after an internal error */
return( -1 );
}
+ if( psa_hash_finish( &hash_operation, hash, sizeof( hash ), &hash_len )
+ != PSA_SUCCESS )
+ {
+ return( -1 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Skip expensive computation on obvious mismatch */
if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) )
return( -1 );
@@ -1967,7 +2490,7 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child,
if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA )
{
return( mbedtls_pk_verify_restartable( &parent->pk,
- child->sig_md, hash, mbedtls_md_get_size( md_info ),
+ child->sig_md, hash, hash_len,
child->sig.p, child->sig.len, &rs_ctx->pk ) );
}
#else
@@ -1975,7 +2498,7 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child,
#endif
return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
- child->sig_md, hash, mbedtls_md_get_size( md_info ),
+ child->sig_md, hash, hash_len,
child->sig.p, child->sig.len ) );
}
@@ -2069,9 +2592,9 @@ static int x509_crt_find_parent_in(
unsigned self_cnt,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_crt *parent, *fallback_parent;
- int signature_is_good, fallback_signature_is_good;
+ int signature_is_good = 0, fallback_signature_is_good;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* did we have something in progress? */
@@ -2192,7 +2715,7 @@ static int x509_crt_find_parent(
unsigned self_cnt,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_crt *search_list;
*parent_is_trusted = 1;
@@ -2317,13 +2840,15 @@ static int x509_crt_verify_chain(
mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
mbedtls_x509_crt_verify_chain *ver_chain,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
/* Don't initialize any of those variables here, so that the compiler can
* catch potential issues with jumping ahead when restarting */
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t *flags;
mbedtls_x509_crt_verify_chain_item *cur;
mbedtls_x509_crt *child;
@@ -2332,6 +2857,7 @@ static int x509_crt_verify_chain(
int child_is_trusted;
int signature_is_good;
unsigned self_cnt;
+ mbedtls_x509_crt *cur_trust_ca = NULL;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* resume if we had an operation in progress */
@@ -2391,8 +2917,32 @@ static int x509_crt_verify_chain(
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
find_parent:
#endif
+
+ /* Obtain list of potential trusted signers from CA callback,
+ * or use statically provided list. */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ if( f_ca_cb != NULL )
+ {
+ mbedtls_x509_crt_free( ver_chain->trust_ca_cb_result );
+ mbedtls_free( ver_chain->trust_ca_cb_result );
+ ver_chain->trust_ca_cb_result = NULL;
+
+ ret = f_ca_cb( p_ca_cb, child, &ver_chain->trust_ca_cb_result );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
+
+ cur_trust_ca = ver_chain->trust_ca_cb_result;
+ }
+ else
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+ {
+ ((void) f_ca_cb);
+ ((void) p_ca_cb);
+ cur_trust_ca = trust_ca;
+ }
+
/* Look for a parent in trusted CAs or up the chain */
- ret = x509_crt_find_parent( child, trust_ca, &parent,
+ ret = x509_crt_find_parent( child, cur_trust_ca, &parent,
&parent_is_trusted, &signature_is_good,
ver_chain->len - 1, self_cnt, rs_ctx );
@@ -2481,6 +3031,25 @@ static int x509_crt_check_cn( const mbedtls_x509_buf *name,
}
/*
+ * Check for SAN match, see RFC 5280 Section 4.2.1.6
+ */
+static int x509_crt_check_san( const mbedtls_x509_buf *name,
+ const char *cn, size_t cn_len )
+{
+ const unsigned char san_type = (unsigned char) name->tag &
+ MBEDTLS_ASN1_TAG_VALUE_MASK;
+
+ /* dNSName */
+ if( san_type == MBEDTLS_X509_SAN_DNS_NAME )
+ return( x509_crt_check_cn( name, cn, cn_len ) );
+
+ /* (We may handle other types here later.) */
+
+ /* Unrecognized type */
+ return( -1 );
+}
+
+/*
* Verify the requested CN - only call this if cn is not NULL!
*/
static void x509_crt_verify_name( const mbedtls_x509_crt *crt,
@@ -2495,7 +3064,7 @@ static void x509_crt_verify_name( const mbedtls_x509_crt *crt,
{
for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next )
{
- if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 )
+ if( x509_crt_check_san( &cur->buf, cn, cn_len ) == 0 )
break;
}
@@ -2527,7 +3096,7 @@ static int x509_crt_merge_flags_with_cb(
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned i;
uint32_t cur_flags;
const mbedtls_x509_crt_verify_chain_item *cur;
@@ -2548,36 +3117,6 @@ static int x509_crt_merge_flags_with_cb(
}
/*
- * Verify the certificate validity (default profile, not restartable)
- */
-int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
- mbedtls_x509_crt *trust_ca,
- mbedtls_x509_crl *ca_crl,
- const char *cn, uint32_t *flags,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
-{
- return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
- &mbedtls_x509_crt_profile_default, cn, flags,
- f_vrfy, p_vrfy, NULL ) );
-}
-
-/*
- * Verify the certificate validity (user-chosen profile, not restartable)
- */
-int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
- mbedtls_x509_crt *trust_ca,
- mbedtls_x509_crl *ca_crl,
- const mbedtls_x509_crt_profile *profile,
- const char *cn, uint32_t *flags,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
-{
- return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
- profile, cn, flags, f_vrfy, p_vrfy, NULL ) );
-}
-
-/*
* Verify the certificate validity, with profile, restartable version
*
* This function:
@@ -2586,17 +3125,26 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
* as that isn't done as part of chain building/verification currently
* - builds and verifies the chain
* - then calls the callback and merges the flags
+ *
+ * The parameters pairs `trust_ca`, `ca_crl` and `f_ca_cb`, `p_ca_cb`
+ * are mutually exclusive: If `f_ca_cb != NULL`, it will be used by the
+ * verification routine to search for trusted signers, and CRLs will
+ * be disabled. Otherwise, `trust_ca` will be used as the static list
+ * of trusted signers, and `ca_crl` will be use as the static list
+ * of CRLs.
*/
-int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
+static int x509_crt_verify_restartable_ca_cb( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_pk_type_t pk_type;
mbedtls_x509_crt_verify_chain ver_chain;
uint32_t ee_flags;
@@ -2625,7 +3173,8 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
/* Check the chain */
- ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile,
+ ret = x509_crt_verify_chain( crt, trust_ca, ca_crl,
+ f_ca_cb, p_ca_cb, profile,
&ver_chain, rs_ctx );
if( ret != 0 )
@@ -2638,6 +3187,13 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy );
exit:
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ mbedtls_x509_crt_free( ver_chain.trust_ca_cb_result );
+ mbedtls_free( ver_chain.trust_ca_cb_result );
+ ver_chain.trust_ca_cb_result = NULL;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
mbedtls_x509_crt_restart_free( rs_ctx );
@@ -2661,6 +3217,77 @@ exit:
return( 0 );
}
+
+/*
+ * Verify the certificate validity (default profile, not restartable)
+ */
+int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt *trust_ca,
+ mbedtls_x509_crl *ca_crl,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy )
+{
+ return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
+ NULL, NULL,
+ &mbedtls_x509_crt_profile_default,
+ cn, flags,
+ f_vrfy, p_vrfy, NULL ) );
+}
+
+/*
+ * Verify the certificate validity (user-chosen profile, not restartable)
+ */
+int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt *trust_ca,
+ mbedtls_x509_crl *ca_crl,
+ const mbedtls_x509_crt_profile *profile,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy )
+{
+ return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
+ NULL, NULL,
+ profile, cn, flags,
+ f_vrfy, p_vrfy, NULL ) );
+}
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+/*
+ * Verify the certificate validity (user-chosen profile, CA callback,
+ * not restartable).
+ */
+int mbedtls_x509_crt_verify_with_ca_cb( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb,
+ const mbedtls_x509_crt_profile *profile,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy )
+{
+ return( x509_crt_verify_restartable_ca_cb( crt, NULL, NULL,
+ f_ca_cb, p_ca_cb,
+ profile, cn, flags,
+ f_vrfy, p_vrfy, NULL ) );
+}
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
+int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt *trust_ca,
+ mbedtls_x509_crl *ca_crl,
+ const mbedtls_x509_crt_profile *profile,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy,
+ mbedtls_x509_crt_restart_ctx *rs_ctx )
+{
+ return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
+ NULL, NULL,
+ profile, cn, flags,
+ f_vrfy, p_vrfy, rs_ctx ) );
+}
+
+
/*
* Initialize a certificate chain
*/
@@ -2730,7 +3357,17 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
mbedtls_free( seq_prv );
}
- if( cert_cur->raw.p != NULL )
+ seq_cur = cert_cur->certificate_policies.next;
+ while( seq_cur != NULL )
+ {
+ seq_prv = seq_cur;
+ seq_cur = seq_cur->next;
+ mbedtls_platform_zeroize( seq_prv,
+ sizeof( mbedtls_x509_sequence ) );
+ mbedtls_free( seq_prv );
+ }
+
+ if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
{
mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len );
mbedtls_free( cert_cur->raw.p );
diff --git a/thirdparty/mbedtls/library/x509_csr.c b/thirdparty/mbedtls/library/x509_csr.c
index 663047d516..e259410d07 100644
--- a/thirdparty/mbedtls/library/x509_csr.c
+++ b/thirdparty/mbedtls/library/x509_csr.c
@@ -2,13 +2,7 @@
* X.509 Certificate Signing Request (CSR) parsing
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -54,15 +27,12 @@
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CSR_PARSE_C)
#include "mbedtls/x509_csr.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
@@ -93,7 +63,7 @@ static int x509_csr_get_version( unsigned char **p,
const unsigned char *end,
int *ver )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
{
@@ -103,7 +73,7 @@ static int x509_csr_get_version( unsigned char **p,
return( 0 );
}
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION, ret ) );
}
return( 0 );
@@ -115,7 +85,7 @@ static int x509_csr_get_version( unsigned char **p,
int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
const unsigned char *buf, size_t buflen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
unsigned char *p, *end;
mbedtls_x509_buf sig_params;
@@ -161,8 +131,8 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
if( len != (size_t) ( end - p ) )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
/*
@@ -174,7 +144,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
end = p + len;
@@ -206,7 +176,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
@@ -240,7 +210,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
p += len;
@@ -274,8 +244,8 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
if( p != end )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
return( 0 );
@@ -287,7 +257,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
{
#if defined(MBEDTLS_PEM_PARSE_C)
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t use_len;
mbedtls_pem_context pem;
#endif
@@ -337,7 +307,7 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz
*/
int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -361,7 +331,7 @@ int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
const mbedtls_x509_csr *csr )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
char *p;
char key_size_str[BEFORE_COLON];
diff --git a/thirdparty/mbedtls/library/x509write_crt.c b/thirdparty/mbedtls/library/x509write_crt.c
index aaffd14c86..184c90cd33 100644
--- a/thirdparty/mbedtls/library/x509write_crt.c
+++ b/thirdparty/mbedtls/library/x509write_crt.c
@@ -2,13 +2,7 @@
* X.509 certificate writing
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* References:
@@ -50,19 +23,16 @@
* - attributes: PKCS#9 v2.0 aka RFC 2985
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CRT_WRITE_C)
#include "mbedtls/x509_crt.h"
-#include "mbedtls/oid.h"
#include "mbedtls/asn1write.h"
-#include "mbedtls/sha1.h"
+#include "mbedtls/error.h"
+#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/sha1.h"
#include <string.h>
@@ -70,16 +40,6 @@
#include "mbedtls/pem.h"
#endif /* MBEDTLS_PEM_WRITE_C */
-/*
- * For the currently used signature algorithms the buffer to store any signature
- * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
- */
-#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
-#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
-#else
-#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
-#endif
-
void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
{
memset( ctx, 0, sizeof( mbedtls_x509write_cert ) );
@@ -138,7 +98,7 @@ int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx,
const mbedtls_mpi *serial )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 )
return( ret );
@@ -175,7 +135,7 @@ int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
int is_ca, int max_pathlen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[9];
unsigned char *c = buf + sizeof(buf);
size_t len = 0;
@@ -209,7 +169,7 @@ int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
#if defined(MBEDTLS_SHA1_C)
int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
unsigned char *c = buf + sizeof(buf);
size_t len = 0;
@@ -237,7 +197,7 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct
int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
unsigned char *c = buf + sizeof( buf );
size_t len = 0;
@@ -270,46 +230,33 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *
}
#endif /* MBEDTLS_SHA1_C */
-static size_t crt_get_unused_bits_for_named_bitstring( unsigned char bitstring,
- size_t bit_offset )
-{
- size_t unused_bits;
-
- /* Count the unused bits removing trailing 0s */
- for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
- if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
- break;
-
- return( unused_bits );
-}
-
int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
unsigned int key_usage )
{
- unsigned char buf[4], ku;
+ unsigned char buf[5] = {0}, ku[2] = {0};
unsigned char *c;
- int ret;
- size_t unused_bits;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
MBEDTLS_X509_KU_NON_REPUDIATION |
MBEDTLS_X509_KU_KEY_ENCIPHERMENT |
MBEDTLS_X509_KU_DATA_ENCIPHERMENT |
MBEDTLS_X509_KU_KEY_AGREEMENT |
MBEDTLS_X509_KU_KEY_CERT_SIGN |
- MBEDTLS_X509_KU_CRL_SIGN;
+ MBEDTLS_X509_KU_CRL_SIGN |
+ MBEDTLS_X509_KU_ENCIPHER_ONLY |
+ MBEDTLS_X509_KU_DECIPHER_ONLY;
/* Check that nothing other than the allowed flags is set */
if( ( key_usage & ~allowed_bits ) != 0 )
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
- c = buf + 4;
- ku = (unsigned char)key_usage;
- unused_bits = crt_get_unused_bits_for_named_bitstring( ku, 1 );
- ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 8 - unused_bits );
+ c = buf + 5;
+ MBEDTLS_PUT_UINT16_LE( key_usage, ku, 0 );
+ ret = mbedtls_asn1_write_named_bitstring( &c, buf, ku, 9 );
if( ret < 0 )
return( ret );
- else if( ret < 3 || ret > 4 )
+ else if( ret < 3 || ret > 5 )
return( MBEDTLS_ERR_X509_INVALID_FORMAT );
ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
@@ -324,18 +271,13 @@ int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
unsigned char ns_cert_type )
{
- unsigned char buf[4];
+ unsigned char buf[4] = {0};
unsigned char *c;
- size_t unused_bits;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
c = buf + 4;
- unused_bits = crt_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
- ret = mbedtls_asn1_write_bitstring( &c,
- buf,
- &ns_cert_type,
- 8 - unused_bits );
+ ret = mbedtls_asn1_write_named_bitstring( &c, buf, &ns_cert_type, 8 );
if( ret < 3 || ret > 4 )
return( ret );
@@ -351,7 +293,7 @@ int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
static int x509_write_time( unsigned char **p, unsigned char *start,
const char *t, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
/*
@@ -384,12 +326,12 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const char *sig_oid;
size_t sig_oid_len = 0;
unsigned char *c, *c2;
unsigned char hash[64];
- unsigned char sig[SIGNATURE_MAX_SIZE];
+ unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
size_t len = 0;
mbedtls_pk_type_t pk_alg;
@@ -578,7 +520,7 @@ int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen;
if( ( ret = mbedtls_x509write_crt_der( crt, buf, size,
diff --git a/thirdparty/mbedtls/library/x509write_csr.c b/thirdparty/mbedtls/library/x509write_csr.c
index 60cf12379f..afda950341 100644
--- a/thirdparty/mbedtls/library/x509write_csr.c
+++ b/thirdparty/mbedtls/library/x509write_csr.c
@@ -2,13 +2,7 @@
* X.509 Certificate Signing Request writing
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* References:
@@ -49,19 +22,21 @@
* - attributes: PKCS#9 v2.0 aka RFC 2985
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CSR_WRITE_C)
#include "mbedtls/x509_csr.h"
-#include "mbedtls/oid.h"
#include "mbedtls/asn1write.h"
+#include "mbedtls/error.h"
+#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif
+
#include <string.h>
#include <stdlib.h>
@@ -69,16 +44,6 @@
#include "mbedtls/pem.h"
#endif
-/*
- * For the currently used signature algorithms the buffer to store any signature
- * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
- */
-#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
-#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
-#else
-#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
-#endif
-
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -124,35 +89,17 @@ int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
0, val, val_len );
}
-static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring,
- size_t bit_offset )
-{
- size_t unused_bits;
-
- /* Count the unused bits removing trailing 0s */
- for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
- if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
- break;
-
- return( unused_bits );
-}
-
int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
{
- unsigned char buf[4];
+ unsigned char buf[4] = {0};
unsigned char *c;
- size_t unused_bits;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
c = buf + 4;
- unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 );
- ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits );
-
- if( ret < 0 )
+ ret = mbedtls_asn1_write_named_bitstring( &c, buf, &key_usage, 8 );
+ if( ret < 3 || ret > 4 )
return( ret );
- else if( ret < 3 || ret > 4 )
- return( MBEDTLS_ERR_X509_INVALID_FORMAT );
ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
@@ -166,22 +113,14 @@ int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned ch
int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
unsigned char ns_cert_type )
{
- unsigned char buf[4];
+ unsigned char buf[4] = {0};
unsigned char *c;
- size_t unused_bits;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
c = buf + 4;
- unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
- ret = mbedtls_asn1_write_bitstring( &c,
- buf,
- &ns_cert_type,
- 8 - unused_bits );
-
- if( ret < 0 )
- return( ret );
- else if( ret < 3 || ret > 4 )
+ ret = mbedtls_asn1_write_named_bitstring( &c, buf, &ns_cert_type, 8 );
+ if( ret < 3 || ret > 4 )
return( ret );
ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
@@ -200,7 +139,7 @@ static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const char *sig_oid;
size_t sig_oid_len = 0;
unsigned char *c, *c2;
@@ -208,6 +147,11 @@ static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
size_t len = 0;
mbedtls_pk_type_t pk_alg;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
+ size_t hash_len;
+ psa_algorithm_t hash_alg = mbedtls_psa_translate_md( ctx->md_alg );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Write the CSR backwards starting from the end of buf */
c = buf + size;
@@ -273,10 +217,23 @@ static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
* Sign the written CSR data into the sig buffer
* Note: hash errors can happen only after an internal error
*/
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( psa_hash_setup( &hash_operation, hash_alg ) != PSA_SUCCESS )
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
+
+ if( psa_hash_update( &hash_operation, c, len ) != PSA_SUCCESS )
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
+
+ if( psa_hash_finish( &hash_operation, hash, sizeof( hash ), &hash_len )
+ != PSA_SUCCESS )
+ {
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
+ }
+#else /* MBEDTLS_USE_PSA_CRYPTO */
ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
if( ret != 0 )
return( ret );
-
+#endif
if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
f_rng, p_rng ) ) != 0 )
{
@@ -341,7 +298,7 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf,
int ret;
unsigned char *sig;
- if( ( sig = mbedtls_calloc( 1, SIGNATURE_MAX_SIZE ) ) == NULL )
+ if( ( sig = mbedtls_calloc( 1, MBEDTLS_PK_SIGNATURE_MAX_SIZE ) ) == NULL )
{
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
}
@@ -361,18 +318,17 @@ int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, s
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
- unsigned char output_buf[4096];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen = 0;
- if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
+ if( ( ret = mbedtls_x509write_csr_der( ctx, buf, size,
f_rng, p_rng ) ) < 0 )
{
return( ret );
}
if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
- output_buf + sizeof(output_buf) - ret,
+ buf + size - ret,
ret, buf, size, &olen ) ) != 0 )
{
return( ret );
diff --git a/thirdparty/mbedtls/library/xtea.c b/thirdparty/mbedtls/library/xtea.c
index 4e62817579..77f6cb6f67 100644
--- a/thirdparty/mbedtls/library/xtea.c
+++ b/thirdparty/mbedtls/library/xtea.c
@@ -2,13 +2,7 @@
* An 32-bit implementation of the XTEA algorithm
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_XTEA_C)
@@ -68,29 +37,6 @@
#if !defined(MBEDTLS_XTEA_ALT)
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
void mbedtls_xtea_init( mbedtls_xtea_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_xtea_context ) );
@@ -115,7 +61,7 @@ void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16]
for( i = 0; i < 4; i++ )
{
- GET_UINT32_BE( ctx->k[i], key, i << 2 );
+ ctx->k[i] = MBEDTLS_GET_UINT32_BE( key, i << 2 );
}
}
@@ -129,8 +75,8 @@ int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode,
k = ctx->k;
- GET_UINT32_BE( v0, input, 0 );
- GET_UINT32_BE( v1, input, 4 );
+ v0 = MBEDTLS_GET_UINT32_BE( input, 0 );
+ v1 = MBEDTLS_GET_UINT32_BE( input, 4 );
if( mode == MBEDTLS_XTEA_ENCRYPT )
{
@@ -155,8 +101,8 @@ int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode,
}
}
- PUT_UINT32_BE( v0, output, 0 );
- PUT_UINT32_BE( v1, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( v0, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( v1, output, 4 );
return( 0 );
}