Commit 5c8af3c4 authored by Nathaniel Wesley Filardo's avatar Nathaniel Wesley Filardo Committed by Marcel Stör
Browse files

Update mbedTLS to 2.7.0 (#2267)

* mbedtls 2.7.0 (mbedtls-2.7.0-0-g32605dc8)

Wholesale import, with a few changes from earlier preserved through.
Ideally we would soon get to the point of having no divergences from
upstream.

* tls: add function to adjust mbedTLS debug level
parent f2d605d2
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file ssl_cookie.h * \file ssl_cookie.h
* *
* \brief DTLS cookie callbacks implementation * \brief DTLS cookie callbacks implementation
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
......
/** /**
* \file ssl_ticket.h * \file ssl_internal.h
* *
* \brief Internal functions shared by the SSL modules * \brief Internal functions shared by the SSL modules
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
#define MBEDTLS_SSL_INTERNAL_H #define MBEDTLS_SSL_INTERNAL_H
#include "ssl.h" #include "ssl.h"
#include "cipher.h"
#if defined(MBEDTLS_MD5_C) #if defined(MBEDTLS_MD5_C)
#include "md5.h" #include "md5.h"
...@@ -138,13 +140,33 @@ ...@@ -138,13 +140,33 @@
#define MBEDTLS_SSL_PADDING_ADD 0 #define MBEDTLS_SSL_PADDING_ADD 0
#endif #endif
#define MBEDTLS_SSL_BUFFER_LEN ( MBEDTLS_SSL_MAX_CONTENT_LEN \ #define MBEDTLS_SSL_PAYLOAD_LEN ( MBEDTLS_SSL_MAX_CONTENT_LEN \
+ MBEDTLS_SSL_COMPRESSION_ADD \ + MBEDTLS_SSL_COMPRESSION_ADD \
+ 29 /* counter + header + IV */ \ + MBEDTLS_MAX_IV_LENGTH \
+ MBEDTLS_SSL_MAC_ADD \ + MBEDTLS_SSL_MAC_ADD \
+ MBEDTLS_SSL_PADDING_ADD \ + MBEDTLS_SSL_PADDING_ADD \
) )
/*
* Check that we obey the standard's message size bounds
*/
#if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384
#error Bad configuration - record content too large.
#endif
#if MBEDTLS_SSL_PAYLOAD_LEN > 16384 + 2048
#error Bad configuration - protected record payload too large.
#endif
/* Note: Even though the TLS record header is only 5 bytes
long, we're internally using 8 bytes to store the
implicit sequence number. */
#define MBEDTLS_SSL_HEADER_LEN 13
#define MBEDTLS_SSL_BUFFER_LEN \
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_PAYLOAD_LEN ) )
/* /*
* TLS extension flags (for extensions with outgoing ServerHello content * TLS extension flags (for extensions with outgoing ServerHello content
* that need it (e.g. for RENEGOTIATION_INFO the server already knows because * that need it (e.g. for RENEGOTIATION_INFO the server already knows because
...@@ -600,9 +622,9 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ); ...@@ -600,9 +622,9 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl );
static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ) static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n )
{ {
size_t i; size_t i;
const unsigned char *A = (const unsigned char *) a; volatile const unsigned char *A = (volatile const unsigned char *) a;
const unsigned char *B = (const unsigned char *) b; volatile const unsigned char *B = (volatile const unsigned char *) b;
unsigned char diff = 0; volatile unsigned char diff = 0;
for( i = 0; i < n; i++ ) for( i = 0; i < n; i++ )
diff |= A[i] ^ B[i]; diff |= A[i] ^ B[i];
...@@ -610,6 +632,23 @@ static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t ...@@ -610,6 +632,23 @@ static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t
return( diff ); return( diff );
} }
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
unsigned char *output,
unsigned char *data, size_t data_len );
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
MBEDTLS_SSL_PROTO_TLS1_1 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
unsigned char *output,
unsigned char *data, size_t data_len,
mbedtls_md_type_t md_alg );
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file ssl_ticket.h * \file ssl_ticket.h
* *
* \brief TLS server ticket callbacks implementation * \brief TLS server ticket callbacks implementation
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file threading.h * \file threading.h
* *
* \brief Threading abstraction layer * \brief Threading abstraction layer
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
......
/** /**
* \file timing.h * \file timing.h
* *
* \brief Portable interface to the CPU cycle counter * \brief Portable interface to timeouts and to the CPU cycle counter
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
...@@ -65,6 +66,9 @@ extern volatile int mbedtls_timing_alarmed; ...@@ -65,6 +66,9 @@ extern volatile int mbedtls_timing_alarmed;
* \warning This is only a best effort! Do not rely on this! * \warning This is only a best effort! Do not rely on this!
* In particular, it is known to be unreliable on virtual * In particular, it is known to be unreliable on virtual
* machines. * machines.
*
* \note This value starts at an unspecified origin and
* may wrap around.
*/ */
unsigned long mbedtls_timing_hardclock( void ); unsigned long mbedtls_timing_hardclock( void );
...@@ -72,7 +76,18 @@ unsigned long mbedtls_timing_hardclock( void ); ...@@ -72,7 +76,18 @@ unsigned long mbedtls_timing_hardclock( void );
* \brief Return the elapsed time in milliseconds * \brief Return the elapsed time in milliseconds
* *
* \param val points to a timer structure * \param val points to a timer structure
* \param reset if set to 1, the timer is restarted * \param reset If 0, query the elapsed time. Otherwise (re)start the timer.
*
* \return Elapsed time since the previous reset in ms. When
* restarting, this is always 0.
*
* \note To initialize a timer, call this function with reset=1.
*
* Determining the elapsed time and resetting the timer is not
* atomic on all platforms, so after the sequence
* `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
* get_timer(0) }` the value time1+time2 is only approximately
* the delay since the first reset.
*/ */
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ); unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset );
...@@ -80,6 +95,7 @@ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int ...@@ -80,6 +95,7 @@ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int
* \brief Setup an alarm clock * \brief Setup an alarm clock
* *
* \param seconds delay before the "mbedtls_timing_alarmed" flag is set * \param seconds delay before the "mbedtls_timing_alarmed" flag is set
* (must be >=0)
* *
* \warning Only one alarm at a time is supported. In a threaded * \warning Only one alarm at a time is supported. In a threaded
* context, this means one for the whole process, not one per * context, this means one for the whole process, not one per
...@@ -91,11 +107,15 @@ void mbedtls_set_alarm( int seconds ); ...@@ -91,11 +107,15 @@ void mbedtls_set_alarm( int seconds );
* \brief Set a pair of delays to watch * \brief Set a pair of delays to watch
* (See \c mbedtls_timing_get_delay().) * (See \c mbedtls_timing_get_delay().)
* *
* \param data Pointer to timing data * \param data Pointer to timing data.
* Must point to a valid \c mbedtls_timing_delay_context struct. * Must point to a valid \c mbedtls_timing_delay_context struct.
* \param int_ms First (intermediate) delay in milliseconds. * \param int_ms First (intermediate) delay in milliseconds.
* The effect if int_ms > fin_ms is unspecified.
* \param fin_ms Second (final) delay in milliseconds. * \param fin_ms Second (final) delay in milliseconds.
* Pass 0 to cancel the current delay. * Pass 0 to cancel the current delay.
*
* \note To set a single delay, either use \c mbedtls_timing_set_timer
* directly or use this function with int_ms == fin_ms.
*/ */
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
...@@ -106,7 +126,7 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); ...@@ -106,7 +126,7 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
* \param data Pointer to timing data * \param data Pointer to timing data
* Must point to a valid \c mbedtls_timing_delay_context struct. * Must point to a valid \c mbedtls_timing_delay_context struct.
* *
* \return -1 if cancelled (fin_ms = 0) * \return -1 if cancelled (fin_ms = 0),
* 0 if none of the delays are passed, * 0 if none of the delays are passed,
* 1 if only the intermediate delay is passed, * 1 if only the intermediate delay is passed,
* 2 if the final delay is passed. * 2 if the final delay is passed.
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file version.h * \file version.h
* *
* \brief Run-time version information * \brief Run-time version information
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
...@@ -38,17 +39,17 @@ ...@@ -38,17 +39,17 @@
* Major, Minor, Patchlevel * Major, Minor, Patchlevel
*/ */
#define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 6 #define MBEDTLS_VERSION_MINOR 7
#define MBEDTLS_VERSION_PATCH 1 #define MBEDTLS_VERSION_PATCH 0
/** /**
* The single version number has the following structure: * The single version number has the following structure:
* MMNNPP00 * MMNNPP00
* Major version | Minor version | Patch version * Major version | Minor version | Patch version
*/ */
#define MBEDTLS_VERSION_NUMBER 0x02060100 #define MBEDTLS_VERSION_NUMBER 0x02070000
#define MBEDTLS_VERSION_STRING "2.6.1" #define MBEDTLS_VERSION_STRING "2.7.0"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.6.1" #define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.7.0"
#if defined(MBEDTLS_VERSION_C) #if defined(MBEDTLS_VERSION_C)
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file x509.h * \file x509.h
* *
* \brief X.509 generic defines and structures * \brief X.509 generic defines and structures
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file x509_crl.h * \file x509_crl.h
* *
* \brief X.509 certificate revocation list parsing * \brief X.509 certificate revocation list parsing
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file x509_crt.h * \file x509_crt.h
* *
* \brief X.509 certificate parsing and writing * \brief X.509 certificate parsing and writing
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
...@@ -373,21 +374,22 @@ int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, ...@@ -373,21 +374,22 @@ int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
/** /**
* \brief Check usage of certificate against extentedJeyUsage. * \brief Check usage of certificate against extendedKeyUsage.
* *
* \param crt Leaf certificate used. * \param crt Leaf certificate used.
* \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or MBEDTLS_OID_CLIENT_AUTH). * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or
* MBEDTLS_OID_CLIENT_AUTH).
* \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()). * \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()).
* *
* \return 0 if this use of the certificate is allowed, * \return 0 if this use of the certificate is allowed,
* MBEDTLS_ERR_X509_BAD_INPUT_DATA if not. * MBEDTLS_ERR_X509_BAD_INPUT_DATA if not.
* *
* \note Usually only makes sense on leaf certificates. * \note Usually only makes sense on leaf certificates.
*/ */
int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
const char *usage_oid, const char *usage_oid,
size_t usage_len ); size_t usage_len );
#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) */ #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
#if defined(MBEDTLS_X509_CRL_PARSE_C) #if defined(MBEDTLS_X509_CRL_PARSE_C)
/** /**
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file x509_csr.h * \file x509_csr.h
* *
* \brief X.509 certificate signing request parsing and writing * \brief X.509 certificate signing request parsing and writing
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* \file xtea.h * \file xtea.h
* *
* \brief XTEA block cipher (32-bit) * \brief XTEA block cipher (32-bit)
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
...@@ -36,6 +37,7 @@ ...@@ -36,6 +37,7 @@
#define MBEDTLS_XTEA_DECRYPT 0 #define MBEDTLS_XTEA_DECRYPT 0
#define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH -0x0028 /**< The data input has an invalid length. */ #define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH -0x0028 /**< The data input has an invalid length. */
#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED -0x0029 /**< XTEA hardware accelerator failed. */
#if !defined(MBEDTLS_XTEA_ALT) #if !defined(MBEDTLS_XTEA_ALT)
// Regular implementation // Regular implementation
......
...@@ -1235,9 +1235,11 @@ static const int aes_test_ctr_len[3] = ...@@ -1235,9 +1235,11 @@ static const int aes_test_ctr_len[3] =
*/ */
int mbedtls_aes_self_test( int verbose ) int mbedtls_aes_self_test( int verbose )
{ {
int ret = 0, i, j, u, v; int ret = 0, i, j, u, mode;
unsigned int keybits;
unsigned char key[32]; unsigned char key[32];
unsigned char buf[64]; unsigned char buf[64];
const unsigned char *aes_tests;
#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) #if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
unsigned char iv[16]; unsigned char iv[16];
#endif #endif
...@@ -1263,45 +1265,52 @@ int mbedtls_aes_self_test( int verbose ) ...@@ -1263,45 +1265,52 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( buf, 0, 16 ); memset( buf, 0, 16 );
if( v == MBEDTLS_AES_DECRYPT ) if( mode == MBEDTLS_AES_DECRYPT )
{ {
mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
aes_tests = aes_test_ecb_dec[u];
for( j = 0; j < 10000; j++ )
mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
} }
else else
{ {
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
aes_tests = aes_test_ecb_enc[u];
for( j = 0; j < 10000; j++ ) }
mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) /*
{ * AES-192 is an optional feature that may be unavailable when
if( verbose != 0 ) * there is an alternative underlying implementation i.e. when
mbedtls_printf( "failed\n" ); * MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{
mbedtls_printf( "skipped\n" );
continue;
}
else if( ret != 0 )
{
goto exit;
}
ret = 1; for( j = 0; j < 10000; j++ )
{
ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
if( ret != 0 )
goto exit; goto exit;
} }
if( memcmp( buf, aes_tests, 16 ) != 0 )
{
ret = 1;
goto exit;
} }
if( verbose != 0 ) if( verbose != 0 )
...@@ -1318,55 +1327,64 @@ int mbedtls_aes_self_test( int verbose ) ...@@ -1318,55 +1327,64 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( iv , 0, 16 ); memset( iv , 0, 16 );
memset( prv, 0, 16 ); memset( prv, 0, 16 );
memset( buf, 0, 16 ); memset( buf, 0, 16 );
if( v == MBEDTLS_AES_DECRYPT ) if( mode == MBEDTLS_AES_DECRYPT )
{ {
mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
aes_tests = aes_test_cbc_dec[u];
for( j = 0; j < 10000; j++ )
mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
} }
else else
{ {
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
aes_tests = aes_test_cbc_enc[u];
}
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{
mbedtls_printf( "skipped\n" );
continue;
}
else if( ret != 0 )
{
goto exit;
}
for( j = 0; j < 10000; j++ ) for( j = 0; j < 10000; j++ )
{
if( mode == MBEDTLS_AES_ENCRYPT )
{ {
unsigned char tmp[16]; unsigned char tmp[16];
mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
memcpy( tmp, prv, 16 ); memcpy( tmp, prv, 16 );
memcpy( prv, buf, 16 ); memcpy( prv, buf, 16 );
memcpy( buf, tmp, 16 ); memcpy( buf, tmp, 16 );
} }
if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
{ if( ret != 0 )
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit; goto exit;
}
}
if( memcmp( buf, aes_tests, 16 ) != 0 )
{
ret = 1;
goto exit;
} }
if( verbose != 0 ) if( verbose != 0 )
...@@ -1384,45 +1402,52 @@ int mbedtls_aes_self_test( int verbose ) ...@@ -1384,45 +1402,52 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, aes_test_cfb128_iv, 16 ); memcpy( iv, aes_test_cfb128_iv, 16 );
memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
offset = 0; offset = 0;
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{
mbedtls_printf( "skipped\n" );
continue;
}
else if( ret != 0 )
{
goto exit;
}
if( v == MBEDTLS_AES_DECRYPT ) if( mode == MBEDTLS_AES_DECRYPT )
{ {
memcpy( buf, aes_test_cfb128_ct[u], 64 ); memcpy( buf, aes_test_cfb128_ct[u], 64 );
mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); aes_tests = aes_test_cfb128_pt;
if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
} }
else else
{ {
memcpy( buf, aes_test_cfb128_pt, 64 ); memcpy( buf, aes_test_cfb128_pt, 64 );
mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); aes_tests = aes_test_cfb128_ct[u];
}
if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
{ if( ret != 0 )
if( verbose != 0 ) goto exit;
mbedtls_printf( "failed\n" );
ret = 1; if( memcmp( buf, aes_tests, 64 ) != 0 )
goto exit; {
} ret = 1;
goto exit;
} }
if( verbose != 0 ) if( verbose != 0 )
...@@ -1440,51 +1465,41 @@ int mbedtls_aes_self_test( int verbose ) ...@@ -1440,51 +1465,41 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CTR-128 (%s): ", mbedtls_printf( " AES-CTR-128 (%s): ",
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
memcpy( key, aes_test_ctr_key[u], 16 ); memcpy( key, aes_test_ctr_key[u], 16 );
offset = 0; offset = 0;
mbedtls_aes_setkey_enc( &ctx, key, 128 ); if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
goto exit;
len = aes_test_ctr_len[u];
if( v == MBEDTLS_AES_DECRYPT ) if( mode == MBEDTLS_AES_DECRYPT )
{ {
len = aes_test_ctr_len[u];
memcpy( buf, aes_test_ctr_ct[u], len ); memcpy( buf, aes_test_ctr_ct[u], len );
aes_tests = aes_test_ctr_pt[u];
mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
buf, buf );
if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
} }
else else
{ {
len = aes_test_ctr_len[u];
memcpy( buf, aes_test_ctr_pt[u], len ); memcpy( buf, aes_test_ctr_pt[u], len );
aes_tests = aes_test_ctr_ct[u];
}
mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
buf, buf ); stream_block, buf, buf );
if( ret != 0 )
if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) goto exit;
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1; if( memcmp( buf, aes_tests, len ) != 0 )
goto exit; {
} ret = 1;
goto exit;
} }
if( verbose != 0 ) if( verbose != 0 )
...@@ -1498,6 +1513,9 @@ int mbedtls_aes_self_test( int verbose ) ...@@ -1498,6 +1513,9 @@ int mbedtls_aes_self_test( int verbose )
ret = 0; ret = 0;
exit: exit:
if( ret != 0 && verbose != 0 )
mbedtls_printf( "failed\n" );
mbedtls_aes_free( &ctx ); mbedtls_aes_free( &ctx );
return( ret ); return( ret );
......
...@@ -63,6 +63,11 @@ static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) { ...@@ -63,6 +63,11 @@ static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) {
volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0; volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0;
} }
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
#define biL (ciL << 3) /* bits in limb */ #define biL (ciL << 3) /* bits in limb */
#define biH (ciL << 2) /* half limb size */ #define biH (ciL << 2) /* half limb size */
...@@ -672,16 +677,20 @@ cleanup: ...@@ -672,16 +677,20 @@ cleanup:
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ) int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
{ {
int ret; int ret;
size_t i, j, n; size_t i, j;
size_t const limbs = CHARS_TO_LIMBS( buflen );
for( n = 0; n < buflen; n++ ) /* Ensure that target MPI has exactly the necessary number of limbs */
if( buf[n] != 0 ) if( X->n != limbs )
break; {
mbedtls_mpi_free( X );
mbedtls_mpi_init( X );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
}
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
for( i = buflen, j = 0; i > n; i--, j++ ) for( i = buflen, j = 0; i > 0; i--, j++ )
X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3); X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
cleanup: cleanup:
...@@ -1882,6 +1891,7 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, ...@@ -1882,6 +1891,7 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
cleanup: cleanup:
mbedtls_zeroize( buf, sizeof( buf ) );
return( ret ); return( ret );
} }
......
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#if !defined(MBEDTLS_CCM_ALT)
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
...@@ -348,6 +350,7 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, ...@@ -348,6 +350,7 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
return( 0 ); return( 0 );
} }
#endif /* !MBEDTLS_CCM_ALT */
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/* /*
......
...@@ -516,14 +516,14 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, ...@@ -516,14 +516,14 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
if( NULL == input || NULL == data_len ) if( NULL == input || NULL == data_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
bad = 0xFF; bad = 0x80;
*data_len = 0; *data_len = 0;
for( i = input_len; i > 0; i-- ) for( i = input_len; i > 0; i-- )
{ {
prev_done = done; prev_done = done;
done |= ( input[i-1] != 0 ); done |= ( input[i - 1] != 0 );
*data_len |= ( i - 1 ) * ( done != prev_done ); *data_len |= ( i - 1 ) * ( done != prev_done );
bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); bad ^= input[i - 1] * ( done != prev_done );
} }
return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
......
...@@ -65,6 +65,8 @@ ...@@ -65,6 +65,8 @@
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
...@@ -164,7 +166,9 @@ exit: ...@@ -164,7 +166,9 @@ exit:
return( ret ); return( ret );
} }
#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
#if !defined(MBEDTLS_CMAC_ALT)
static void cmac_xor_block( unsigned char *output, const unsigned char *input1, static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
const unsigned char *input2, const unsigned char *input2,
const size_t block_size ) const size_t block_size )
...@@ -468,6 +472,8 @@ exit: ...@@ -468,6 +472,8 @@ exit:
} }
#endif /* MBEDTLS_AES_C */ #endif /* MBEDTLS_AES_C */
#endif /* !MBEDTLS_CMAC_ALT */
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* CMAC test data for SP800-38B * CMAC test data for SP800-38B
......
...@@ -94,11 +94,15 @@ int mbedtls_ctr_drbg_seed_entropy_len( ...@@ -94,11 +94,15 @@ int mbedtls_ctr_drbg_seed_entropy_len(
/* /*
* Initialize with an empty key * Initialize with an empty key
*/ */
mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ); 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 ) if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
{
return( ret ); return( ret );
}
return( 0 ); return( 0 );
} }
...@@ -148,6 +152,7 @@ static int block_cipher_df( unsigned char *output, ...@@ -148,6 +152,7 @@ static int block_cipher_df( unsigned char *output,
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
unsigned char *p, *iv; unsigned char *p, *iv;
mbedtls_aes_context aes_ctx; mbedtls_aes_context aes_ctx;
int ret = 0;
int i, j; int i, j;
size_t buf_len, use_len; size_t buf_len, use_len;
...@@ -180,7 +185,10 @@ static int block_cipher_df( unsigned char *output, ...@@ -180,7 +185,10 @@ static int block_cipher_df( unsigned char *output,
for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ ) for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
key[i] = i; key[i] = i;
mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ); if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
/* /*
* Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
...@@ -199,7 +207,10 @@ static int block_cipher_df( unsigned char *output, ...@@ -199,7 +207,10 @@ static int block_cipher_df( unsigned char *output,
use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ); if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
{
goto exit;
}
} }
memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
...@@ -213,20 +224,40 @@ static int block_cipher_df( unsigned char *output, ...@@ -213,20 +224,40 @@ static int block_cipher_df( unsigned char *output,
/* /*
* Do final encryption with reduced data * Do final encryption with reduced data
*/ */
mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ); if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
p = output; p = output;
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
{ {
mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
{
goto exit;
}
memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
} }
exit:
mbedtls_aes_free( &aes_ctx ); mbedtls_aes_free( &aes_ctx );
/*
* tidy up the stack
*/
mbedtls_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( tmp, sizeof( tmp ) );
mbedtls_zeroize( key, sizeof( key ) );
mbedtls_zeroize( chain, sizeof( chain ) );
if( 0 != ret )
{
/*
* wipe partial seed from memory
*/
mbedtls_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
}
return( 0 ); return( ret );
} }
static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
...@@ -235,6 +266,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, ...@@ -235,6 +266,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = tmp; unsigned char *p = tmp;
int i, j; int i, j;
int ret = 0;
memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
...@@ -250,7 +282,10 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, ...@@ -250,7 +282,10 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
/* /*
* Crypt counter block * Crypt counter block
*/ */
mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ); if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
{
return( ret );
}
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
} }
...@@ -261,7 +296,10 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, ...@@ -261,7 +296,10 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
/* /*
* Update key and counter * Update key and counter
*/ */
mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ); if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE ); memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
return( 0 ); return( 0 );
...@@ -289,6 +327,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, ...@@ -289,6 +327,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
{ {
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0; size_t seedlen = 0;
int ret;
if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
...@@ -319,12 +358,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, ...@@ -319,12 +358,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
/* /*
* Reduce to 384 bits * Reduce to 384 bits
*/ */
block_cipher_df( seed, seed, seedlen ); if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
{
return( ret );
}
/* /*
* Update state * Update state
*/ */
ctr_drbg_update_internal( ctx, seed ); if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
{
return( ret );
}
ctx->reseed_counter = 1; ctx->reseed_counter = 1;
return( 0 ); return( 0 );
...@@ -354,15 +399,22 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, ...@@ -354,15 +399,22 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
ctx->prediction_resistance ) ctx->prediction_resistance )
{ {
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
{
return( ret ); return( ret );
}
add_len = 0; add_len = 0;
} }
if( add_len > 0 ) if( add_len > 0 )
{ {
block_cipher_df( add_input, additional, add_len ); if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
ctr_drbg_update_internal( ctx, add_input ); {
return( ret );
}
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
{
return( ret );
}
} }
while( output_len > 0 ) while( output_len > 0 )
...@@ -377,7 +429,10 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, ...@@ -377,7 +429,10 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
/* /*
* Crypt counter block * Crypt counter block
*/ */
mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ); if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
{
return( ret );
}
use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
output_len; output_len;
...@@ -389,7 +444,10 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, ...@@ -389,7 +444,10 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
output_len -= use_len; output_len -= use_len;
} }
ctr_drbg_update_internal( ctx, add_input ); if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
{
return( ret );
}
ctx->reseed_counter++; ctx->reseed_counter++;
...@@ -430,20 +488,20 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char ...@@ -430,20 +488,20 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
goto exit; 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; ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
goto exit; else
} ret = 0;
ret = 0;
exit: exit:
mbedtls_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( ret ); 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; FILE *f;
size_t n; size_t n;
unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
...@@ -462,14 +520,16 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char ...@@ -462,14 +520,16 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char
} }
if( fread( buf, 1, n, f ) != n ) if( fread( buf, 1, n, f ) != n )
{ ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
fclose( f ); else
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); mbedtls_ctr_drbg_update( ctx, buf, n );
}
fclose( f ); fclose( f );
mbedtls_ctr_drbg_update( ctx, buf, n ); mbedtls_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
} }
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#if !defined(MBEDTLS_DHM_ALT)
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0; volatile unsigned char *p = v; while( n-- ) *p++ = 0;
...@@ -93,6 +94,9 @@ static int dhm_read_bignum( mbedtls_mpi *X, ...@@ -93,6 +94,9 @@ static int dhm_read_bignum( mbedtls_mpi *X,
* *
* Parameter should be: 2 <= public_param <= P - 2 * Parameter should be: 2 <= public_param <= P - 2
* *
* This means that we need to return an error if
* public_param < 2 or public_param > P-2
*
* For more information on the attack, see: * For more information on the attack, see:
* http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
* http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
...@@ -100,17 +104,17 @@ static int dhm_read_bignum( mbedtls_mpi *X, ...@@ -100,17 +104,17 @@ static int dhm_read_bignum( mbedtls_mpi *X,
static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P ) static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
{ {
mbedtls_mpi L, U; mbedtls_mpi L, U;
int ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; int ret = 0;
mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
if( mbedtls_mpi_cmp_mpi( param, &L ) >= 0 && if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
mbedtls_mpi_cmp_mpi( param, &U ) <= 0 ) mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
{ {
ret = 0; ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
} }
cleanup: cleanup:
...@@ -187,10 +191,15 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, ...@@ -187,10 +191,15 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
/* /*
* export P, G, GX * export P, G, GX
*/ */
#define DHM_MPI_EXPORT(X,n) \ #define DHM_MPI_EXPORT( X, n ) \
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, p + 2, n ) ); \ do { \
*p++ = (unsigned char)( n >> 8 ); \ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
*p++ = (unsigned char)( n ); p += n; p + 2, \
( n ) ) ); \
*p++ = (unsigned char)( ( n ) >> 8 ); \
*p++ = (unsigned char)( ( n ) ); \
p += ( n ); \
} while( 0 )
n1 = mbedtls_mpi_size( &ctx->P ); n1 = mbedtls_mpi_size( &ctx->P );
n2 = mbedtls_mpi_size( &ctx->G ); n2 = mbedtls_mpi_size( &ctx->G );
...@@ -201,7 +210,7 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, ...@@ -201,7 +210,7 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
DHM_MPI_EXPORT( &ctx->G , n2 ); DHM_MPI_EXPORT( &ctx->G , n2 );
DHM_MPI_EXPORT( &ctx->GX, n3 ); DHM_MPI_EXPORT( &ctx->GX, n3 );
*olen = p - output; *olen = p - output;
ctx->len = n1; ctx->len = n1;
...@@ -213,6 +222,28 @@ cleanup: ...@@ -213,6 +222,28 @@ cleanup:
return( 0 ); return( 0 );
} }
/*
* Set prime modulus and generator
*/
int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
const mbedtls_mpi *P,
const mbedtls_mpi *G )
{
int ret;
if( ctx == NULL || P == NULL || G == NULL )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
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 );
}
ctx->len = mbedtls_mpi_size( &ctx->P );
return( 0 );
}
/* /*
* Import the peer's public value G^Y * Import the peer's public value G^Y
*/ */
...@@ -400,10 +431,11 @@ cleanup: ...@@ -400,10 +431,11 @@ cleanup:
*/ */
void mbedtls_dhm_free( mbedtls_dhm_context *ctx ) void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
{ {
mbedtls_mpi_free( &ctx->pX); mbedtls_mpi_free( &ctx->Vf ); mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf );
mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY ); mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP );
mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
mbedtls_mpi_free( &ctx->P ); mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X );
mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->P );
mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
} }
...@@ -542,7 +574,10 @@ static int load_file( const char *path, unsigned char **buf, size_t *n ) ...@@ -542,7 +574,10 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
if( fread( *buf, 1, *n, f ) != *n ) if( fread( *buf, 1, *n, f ) != *n )
{ {
fclose( f ); fclose( f );
mbedtls_zeroize( *buf, *n + 1 );
mbedtls_free( *buf ); mbedtls_free( *buf );
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
} }
...@@ -577,6 +612,7 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) ...@@ -577,6 +612,7 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
} }
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */
#endif /* MBEDTLS_ASN1_PARSE_C */ #endif /* MBEDTLS_ASN1_PARSE_C */
#endif /* MBEDTLS_DHM_ALT */
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <string.h> #include <string.h>
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
/* /*
* Generate public key: simple wrapper around mbedtls_ecp_gen_keypair * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair
*/ */
...@@ -47,7 +48,9 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp ...@@ -47,7 +48,9 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp
{ {
return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
} }
#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
/* /*
* Compute shared secret (SEC1 3.3.1) * Compute shared secret (SEC1 3.3.1)
*/ */
...@@ -81,6 +84,7 @@ cleanup: ...@@ -81,6 +84,7 @@ cleanup:
return( ret ); return( ret );
} }
#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
/* /*
* Initialize context * Initialize context
......
...@@ -65,6 +65,7 @@ cleanup: ...@@ -65,6 +65,7 @@ cleanup:
return( ret ); return( ret );
} }
#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
/* /*
* Compute ECDSA signature of a hashed message (SEC1 4.1.3) * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
* Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
...@@ -81,6 +82,10 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, ...@@ -81,6 +82,10 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
if( grp->N.p == NULL ) if( grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
/* Make sure d is in range 1..n-1 */
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
return( MBEDTLS_ERR_ECP_INVALID_KEY );
mbedtls_ecp_point_init( &R ); mbedtls_ecp_point_init( &R );
mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t ); mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
...@@ -153,6 +158,7 @@ cleanup: ...@@ -153,6 +158,7 @@ cleanup:
return( ret ); return( ret );
} }
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/* /*
...@@ -192,6 +198,7 @@ cleanup: ...@@ -192,6 +198,7 @@ cleanup:
} }
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
/* /*
* Verify ECDSA signature of hashed message (SEC1 4.1.4) * Verify ECDSA signature of hashed message (SEC1 4.1.4)
* Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
...@@ -277,6 +284,7 @@ cleanup: ...@@ -277,6 +284,7 @@ cleanup:
return( ret ); return( ret );
} }
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
/* /*
* Convert a signature (given by context) to ASN.1 * Convert a signature (given by context) to ASN.1
...@@ -402,6 +410,7 @@ cleanup: ...@@ -402,6 +410,7 @@ cleanup:
return( ret ); return( ret );
} }
#if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
/* /*
* Generate key pair * Generate key pair
*/ */
...@@ -411,6 +420,7 @@ int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, ...@@ -411,6 +420,7 @@ int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
return( mbedtls_ecp_group_load( &ctx->grp, gid ) || return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ); mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
} }
#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
/* /*
* Set context from an mbedtls_ecp_keypair * Set context from an mbedtls_ecp_keypair
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment