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

Update TLS protocol support (#2587)

* Update TLS protocol support

TLS1.0 is past PCI's EOL; BEAST is no more
Enable elliptic curve key exchanges
	Do not enable the smallest ECs for security
	Do not enable the largest ECs for computational time
	Do not enable 25519 (sad) because it doesn't go across the wire
Drop non-PFS key exchanges
Drop ARC4, Blowfish, DES, genprime, XTEA code
Drop renegotiation support completely
	It takes so much heap that it's not likely to work out well

Tidy handling of SSL_BUFFER_SIZE

Update docs
Drop mention of startcom, since they are no more, for letsencrypt

* Update mbedtls to 2.7.7

Preserve our vsnprintf and platform hacks

* Introduce TLS maximum fragment size knob

Reduce buffer size to 4Ki by default and advertize that.  That's the
largest we can advertize with the TLS MFL extension, so there's no
point in making them larger.  The truly adventurous can re-raise
SSL_BUFFER_SIZE and undefine the SSL_MAX_FRAGMENT_LENGTH_CODE and get
back to the earlier behavior.

* Default to mbedTLS debug with DEVELOP_VERSION
parent c6653b59
...@@ -318,6 +318,10 @@ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ) ...@@ -318,6 +318,10 @@ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
} }
/* Get a specific byte, without range checks. */
#define GET_BYTE( X, i ) \
( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
/* /*
* Set a bit to a specific value of 0 or 1 * Set a bit to a specific value of 0 or 1
*/ */
...@@ -701,19 +705,40 @@ cleanup: ...@@ -701,19 +705,40 @@ cleanup:
/* /*
* Export X into unsigned binary data, big endian * Export X into unsigned binary data, big endian
*/ */
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen ) int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
unsigned char *buf, size_t buflen )
{ {
size_t i, j, n; size_t stored_bytes = X->n * ciL;
size_t bytes_to_copy;
n = mbedtls_mpi_size( X ); unsigned char *p;
size_t i;
if( buflen < n ) if( stored_bytes < buflen )
{
/* There is enough space in the output buffer. Write initial
* null bytes and record the position at which to start
* writing the significant bytes. In this case, the execution
* trace of this function does not depend on the value of the
* number. */
bytes_to_copy = stored_bytes;
p = buf + buflen - stored_bytes;
memset( buf, 0, buflen - stored_bytes );
}
else
{
/* The output buffer is smaller than the allocated size of X.
* However X may fit if its leading bytes are zero. */
bytes_to_copy = buflen;
p = buf;
for( i = bytes_to_copy; i < stored_bytes; i++ )
{
if( GET_BYTE( X, i ) != 0 )
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
}
}
memset( buf, 0, buflen ); for( i = 0; i < bytes_to_copy; i++ )
p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
return( 0 ); return( 0 );
} }
...@@ -1623,7 +1648,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi ...@@ -1623,7 +1648,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
int neg; int neg;
if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
...@@ -2053,12 +2078,12 @@ cleanup: ...@@ -2053,12 +2078,12 @@ cleanup:
/* /*
* Miller-Rabin pseudo-primality test (HAC 4.24) * Miller-Rabin pseudo-primality test (HAC 4.24)
*/ */
static int mpi_miller_rabin( const mbedtls_mpi *X, static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng ) void *p_rng )
{ {
int ret, count; int ret, count;
size_t i, j, k, n, s; size_t i, j, k, s;
mbedtls_mpi W, R, T, A, RR; mbedtls_mpi W, R, T, A, RR;
mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A ); mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
...@@ -2074,27 +2099,12 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, ...@@ -2074,27 +2099,12 @@ static int mpi_miller_rabin( const mbedtls_mpi *X,
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
i = mbedtls_mpi_bitlen( X ); i = mbedtls_mpi_bitlen( X );
/*
* HAC, table 4.4
*/
n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
for( i = 0; i < n; i++ ) for( i = 0; i < rounds; i++ )
{ {
/* /*
* pick a random A, 1 < A < |X| - 1 * pick a random A, 1 < A < |X| - 1
*/ */
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
if( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 )
{
j = mbedtls_mpi_bitlen( &A ) - mbedtls_mpi_bitlen( &W );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j + 1 ) );
}
A.p[0] |= 3;
count = 0; count = 0;
do { do {
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
...@@ -2102,7 +2112,7 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, ...@@ -2102,7 +2112,7 @@ static int mpi_miller_rabin( const mbedtls_mpi *X,
j = mbedtls_mpi_bitlen( &A ); j = mbedtls_mpi_bitlen( &A );
k = mbedtls_mpi_bitlen( &W ); k = mbedtls_mpi_bitlen( &W );
if (j > k) { if (j > k) {
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j - k ) ); A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1;
} }
if (count++ > 30) { if (count++ > 30) {
...@@ -2157,7 +2167,7 @@ cleanup: ...@@ -2157,7 +2167,7 @@ cleanup:
/* /*
* Pseudo-primality test: small factors, then Miller-Rabin * Pseudo-primality test: small factors, then Miller-Rabin
*/ */
int mbedtls_mpi_is_prime( const mbedtls_mpi *X, static int mpi_is_prime_internal( const mbedtls_mpi *X, int rounds,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng ) void *p_rng )
{ {
...@@ -2183,7 +2193,17 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X, ...@@ -2183,7 +2193,17 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
return( ret ); return( ret );
} }
return( mpi_miller_rabin( &XX, f_rng, p_rng ) ); return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
}
/*
* Pseudo-primality test, error probability 2^-80
*/
int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return mpi_is_prime_internal( X, 40, f_rng, p_rng );
} }
/* /*
...@@ -2195,6 +2215,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, ...@@ -2195,6 +2215,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
{ {
int ret; int ret;
size_t k, n; size_t k, n;
int rounds;
mbedtls_mpi_uint r; mbedtls_mpi_uint r;
mbedtls_mpi Y; mbedtls_mpi Y;
...@@ -2205,6 +2226,13 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, ...@@ -2205,6 +2226,13 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
n = BITS_TO_LIMBS( nbits ); n = BITS_TO_LIMBS( nbits );
/*
* 2^-80 error probability, number of rounds chosen per HAC, table 4.4
*/
rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 :
( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 :
( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 );
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
k = mbedtls_mpi_bitlen( X ); k = mbedtls_mpi_bitlen( X );
...@@ -2216,7 +2244,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, ...@@ -2216,7 +2244,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
if( dh_flag == 0 ) if( dh_flag == 0 )
{ {
while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) while( ( ret = mpi_is_prime_internal( X, rounds, f_rng, p_rng ) ) != 0 )
{ {
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
goto cleanup; goto cleanup;
...@@ -2252,8 +2280,10 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, ...@@ -2252,8 +2280,10 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
*/ */
if( ( ret = mpi_check_small_factors( X ) ) == 0 && if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
( ret = mpi_check_small_factors( &Y ) ) == 0 && ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 && ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) )
( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 ) == 0 &&
( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) )
== 0 )
{ {
break; break;
} }
......
...@@ -358,7 +358,8 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, ...@@ -358,7 +358,8 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
*/ */
#define NB_TESTS 3 #define NB_TESTS 3
#define CCM_SELFTEST_PT_MAX_LEN 24
#define CCM_SELFTEST_CT_MAX_LEN 32
/* /*
* The data is the same for all tests, only the used length changes * The data is the same for all tests, only the used length changes
*/ */
...@@ -378,7 +379,7 @@ static const unsigned char ad[] = { ...@@ -378,7 +379,7 @@ static const unsigned char ad[] = {
0x10, 0x11, 0x12, 0x13 0x10, 0x11, 0x12, 0x13
}; };
static const unsigned char msg[] = { static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
...@@ -389,7 +390,7 @@ static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; ...@@ -389,7 +390,7 @@ 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 msg_len[NB_TESTS] = { 4, 16, 24 };
static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
static const unsigned char res[NB_TESTS][32] = { static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
...@@ -403,7 +404,13 @@ static const unsigned char res[NB_TESTS][32] = { ...@@ -403,7 +404,13 @@ static const unsigned char res[NB_TESTS][32] = {
int mbedtls_ccm_self_test( int verbose ) int mbedtls_ccm_self_test( int verbose )
{ {
mbedtls_ccm_context ctx; mbedtls_ccm_context ctx;
unsigned char out[32]; /*
* Some hardware accelerators require the input and output buffers
* would be in RAM, because the flash is not accessible.
* Use buffers on the stack to hold the test vectors data.
*/
unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
size_t i; size_t i;
int ret; int ret;
...@@ -422,27 +429,32 @@ int mbedtls_ccm_self_test( int verbose ) ...@@ -422,27 +429,32 @@ int mbedtls_ccm_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 );
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
memcpy( plaintext, msg, msg_len[i] );
ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i], ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
iv, iv_len[i], ad, add_len[i], iv, iv_len[i], ad, add_len[i],
msg, out, plaintext, ciphertext,
out + msg_len[i], tag_len[i] ); ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 || if( ret != 0 ||
memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 ) memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 )
{ {
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
return( 1 ); return( 1 );
} }
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
iv, iv_len[i], ad, add_len[i], iv, iv_len[i], ad, add_len[i],
res[i], out, ciphertext, plaintext,
res[i] + msg_len[i], tag_len[i] ); ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 || if( ret != 0 ||
memcmp( out, msg, msg_len[i] ) != 0 ) memcmp( plaintext, msg, msg_len[i] ) != 0 )
{ {
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
......
...@@ -56,10 +56,6 @@ ...@@ -56,10 +56,6 @@
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
/* 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;
...@@ -215,10 +211,14 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, ...@@ -215,10 +211,14 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len ) const unsigned char *iv, size_t iv_len )
{ {
size_t actual_iv_size; size_t actual_iv_size;
if( NULL == ctx || NULL == ctx->cipher_info )
if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
else if( NULL == iv && iv_len != 0 )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( NULL == iv && iv_len == 0 )
ctx->iv_size = 0;
/* avoid buffer overflow in ctx->iv */ /* avoid buffer overflow in ctx->iv */
if( iv_len > MBEDTLS_MAX_IV_LENGTH ) if( iv_len > MBEDTLS_MAX_IV_LENGTH )
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
...@@ -233,9 +233,11 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, ...@@ -233,9 +233,11 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
if( actual_iv_size > iv_len ) if( actual_iv_size > iv_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
} }
if ( actual_iv_size != 0 )
{
memcpy( ctx->iv, iv, actual_iv_size ); memcpy( ctx->iv, iv, actual_iv_size );
ctx->iv_size = actual_iv_size; ctx->iv_size = actual_iv_size;
}
return( 0 ); return( 0 );
} }
...@@ -325,8 +327,10 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i ...@@ -325,8 +327,10 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
/* /*
* If there is not enough data for a full block, cache it. * If there is not enough data for a full block, cache it.
*/ */
if( ( ctx->operation == MBEDTLS_DECRYPT && if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
ilen <= block_size - ctx->unprocessed_len ) || ilen <= block_size - ctx->unprocessed_len ) ||
( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
ilen < block_size - ctx->unprocessed_len ) ||
( ctx->operation == MBEDTLS_ENCRYPT && ( ctx->operation == MBEDTLS_ENCRYPT &&
ilen < block_size - ctx->unprocessed_len ) ) ilen < block_size - ctx->unprocessed_len ) )
{ {
...@@ -372,9 +376,17 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i ...@@ -372,9 +376,17 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
} }
/* Encryption: only cache partial blocks
* Decryption w/ padding: always keep at least one whole block
* Decryption w/o padding: only cache partial blocks
*/
copy_len = ilen % block_size; copy_len = ilen % block_size;
if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) if( copy_len == 0 &&
ctx->operation == MBEDTLS_DECRYPT &&
NULL != ctx->add_padding)
{
copy_len = block_size; copy_len = block_size;
}
memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
copy_len ); copy_len );
......
...@@ -204,7 +204,7 @@ static const mbedtls_cipher_info_t aes_128_ecb_info = { ...@@ -204,7 +204,7 @@ static const mbedtls_cipher_info_t aes_128_ecb_info = {
MBEDTLS_MODE_ECB, MBEDTLS_MODE_ECB,
128, 128,
"AES-128-ECB", "AES-128-ECB",
16, 0,
0, 0,
16, 16,
&aes_info &aes_info
...@@ -215,7 +215,7 @@ static const mbedtls_cipher_info_t aes_192_ecb_info = { ...@@ -215,7 +215,7 @@ static const mbedtls_cipher_info_t aes_192_ecb_info = {
MBEDTLS_MODE_ECB, MBEDTLS_MODE_ECB,
192, 192,
"AES-192-ECB", "AES-192-ECB",
16, 0,
0, 0,
16, 16,
&aes_info &aes_info
...@@ -226,7 +226,7 @@ static const mbedtls_cipher_info_t aes_256_ecb_info = { ...@@ -226,7 +226,7 @@ static const mbedtls_cipher_info_t aes_256_ecb_info = {
MBEDTLS_MODE_ECB, MBEDTLS_MODE_ECB,
256, 256,
"AES-256-ECB", "AES-256-ECB",
16, 0,
0, 0,
16, 16,
&aes_info &aes_info
......
...@@ -771,7 +771,7 @@ static int cmac_test_subkeys( int verbose, ...@@ -771,7 +771,7 @@ static int cmac_test_subkeys( int verbose,
int block_size, int block_size,
int num_tests ) int num_tests )
{ {
int i, ret; int i, ret = 0;
mbedtls_cipher_context_t ctx; mbedtls_cipher_context_t ctx;
const mbedtls_cipher_info_t *cipher_info; const mbedtls_cipher_info_t *cipher_info;
unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
...@@ -832,6 +832,7 @@ static int cmac_test_subkeys( int verbose, ...@@ -832,6 +832,7 @@ static int cmac_test_subkeys( int verbose,
mbedtls_cipher_free( &ctx ); mbedtls_cipher_free( &ctx );
} }
ret = 0;
goto exit; goto exit;
cleanup: cleanup:
...@@ -853,7 +854,7 @@ static int cmac_test_wth_cipher( int verbose, ...@@ -853,7 +854,7 @@ static int cmac_test_wth_cipher( int verbose,
int num_tests ) int num_tests )
{ {
const mbedtls_cipher_info_t *cipher_info; const mbedtls_cipher_info_t *cipher_info;
int i, ret; int i, ret = 0;
unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX]; unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
cipher_info = mbedtls_cipher_info_from_type( cipher_type ); cipher_info = mbedtls_cipher_info_from_type( cipher_type );
...@@ -887,6 +888,7 @@ static int cmac_test_wth_cipher( int verbose, ...@@ -887,6 +888,7 @@ static int cmac_test_wth_cipher( int verbose,
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
} }
ret = 0;
exit: exit:
return( ret ); return( ret );
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*/ */
/* /*
* The NIST SP 800-90 DRBGs are described in the following publucation. * The NIST SP 800-90 DRBGs are described in the following publication.
* *
* http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
*/ */
...@@ -283,9 +283,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, ...@@ -283,9 +283,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
* Crypt counter block * 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;
return( ret );
}
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
} }
...@@ -297,29 +295,44 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, ...@@ -297,29 +295,44 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
* Update key and counter * 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;
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 ); exit:
mbedtls_zeroize( tmp, sizeof( tmp ) );
return( ret );
} }
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t add_len ) const unsigned char *additional,
size_t add_len )
{ {
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
int ret;
if( add_len > 0 ) if( add_len == 0 )
{ return( 0 );
if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
goto exit;
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
goto exit;
exit:
mbedtls_zeroize( add_input, sizeof( add_input ) );
return( ret );
}
/* Deprecated function, kept for backward compatibility. */
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len )
{
/* MAX_INPUT would be more logical here, but we have to match /* MAX_INPUT would be more logical here, but we have to match
* block_cipher_df()'s limits since we can't propagate errors */ * block_cipher_df()'s limits since we can't propagate errors */
if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
(void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
block_cipher_df( add_input, additional, add_len );
ctr_drbg_update_internal( ctx, add_input );
}
} }
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
...@@ -359,20 +372,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, ...@@ -359,20 +372,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
* Reduce to 384 bits * Reduce to 384 bits
*/ */
if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 ) if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
{ goto exit;
return( ret );
}
/* /*
* Update state * Update state
*/ */
if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 ) if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
{ goto exit;
return( ret );
}
ctx->reseed_counter = 1; ctx->reseed_counter = 1;
return( 0 ); exit:
mbedtls_zeroize( seed, sizeof( seed ) );
return( ret );
} }
int mbedtls_ctr_drbg_random_with_add( void *p_rng, int mbedtls_ctr_drbg_random_with_add( void *p_rng,
...@@ -408,13 +419,9 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, ...@@ -408,13 +419,9 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
if( add_len > 0 ) if( add_len > 0 )
{ {
if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 ) if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
{ goto exit;
return( ret );
}
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
{ goto exit;
return( ret );
}
} }
while( output_len > 0 ) while( output_len > 0 )
...@@ -430,9 +437,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, ...@@ -430,9 +437,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
* Crypt counter block * 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;
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;
...@@ -445,12 +450,13 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, ...@@ -445,12 +450,13 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
} }
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
{ goto exit;
return( ret );
}
ctx->reseed_counter++; ctx->reseed_counter++;
exit:
mbedtls_zeroize( add_input, sizeof( add_input ) );
mbedtls_zeroize( tmp, sizeof( tmp ) );
return( 0 ); return( 0 );
} }
...@@ -522,7 +528,7 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char ...@@ -522,7 +528,7 @@ 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; ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
else else
mbedtls_ctr_drbg_update( ctx, buf, n ); ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
fclose( f ); fclose( f );
......
...@@ -91,7 +91,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, ...@@ -91,7 +91,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
va_start( argp, format ); va_start( argp, format );
#if defined(_WIN32) #if defined(_WIN32)
#if defined(_TRUNCATE) #if defined(_TRUNCATE) && !defined(__MINGW32__)
ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp ); ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
#else #else
ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
......
...@@ -400,6 +400,9 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, ...@@ -400,6 +400,9 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
&ctx->Q, &r, &s ) ) != 0 ) &ctx->Q, &r, &s ) ) != 0 )
goto cleanup; goto cleanup;
/* At this point we know that the buffer starts with a valid signature.
* Return 0 if the buffer just contains the signature, and a specific
* error code if the valid signature is followed by more data. */
if( p != end ) if( p != end )
ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
......
...@@ -409,7 +409,7 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) ...@@ -409,7 +409,7 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
} }
/* /*
* Compare two points lazyly * Compare two points lazily
*/ */
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q ) const mbedtls_ecp_point *Q )
...@@ -1448,7 +1448,12 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, ...@@ -1448,7 +1448,12 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
cleanup: cleanup:
if( T != NULL && ! p_eq_g ) /* There are two cases where T is not stored in grp:
* - P != G
* - An intermediate operation failed before setting grp->T
* In either case, T must be freed.
*/
if( T != NULL && T != grp->T )
{ {
for( i = 0; i < pre_len; i++ ) for( i = 0; i < pre_len; i++ )
mbedtls_ecp_point_free( &T[i] ); mbedtls_ecp_point_free( &T[i] );
......
...@@ -92,6 +92,7 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len ...@@ -92,6 +92,7 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len
#include <sys/syscall.h> #include <sys/syscall.h>
#if defined(SYS_getrandom) #if defined(SYS_getrandom)
#define HAVE_GETRANDOM #define HAVE_GETRANDOM
#include <errno.h>
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
{ {
...@@ -101,47 +102,8 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) ...@@ -101,47 +102,8 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
memset( buf, 0, buflen ); memset( buf, 0, buflen );
#endif #endif
#endif #endif
return( syscall( SYS_getrandom, buf, buflen, flags ) ); return( syscall( SYS_getrandom, buf, buflen, flags ) );
} }
#include <sys/utsname.h>
/* Check if version is at least 3.17.0 */
static int check_version_3_17_plus( void )
{
int minor;
struct utsname un;
const char *ver;
/* Get version information */
uname(&un);
ver = un.release;
/* Check major version; assume a single digit */
if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
return( -1 );
if( ver[0] - '0' > 3 )
return( 0 );
/* Ok, so now we know major == 3, check minor.
* Assume 1 or 2 digits. */
if( ver[2] < '0' || ver[2] > '9' )
return( -1 );
minor = ver[2] - '0';
if( ver[3] >= '0' && ver[3] <= '9' )
minor = 10 * minor + ver[3] - '0';
else if( ver [3] != '.' )
return( -1 );
if( minor < 17 )
return( -1 );
return( 0 );
}
static int has_getrandom = -1;
#endif /* SYS_getrandom */ #endif /* SYS_getrandom */
#endif /* __linux__ */ #endif /* __linux__ */
...@@ -152,22 +114,21 @@ int mbedtls_platform_entropy_poll( void *data, ...@@ -152,22 +114,21 @@ int mbedtls_platform_entropy_poll( void *data,
{ {
FILE *file; FILE *file;
size_t read_len; size_t read_len;
int ret;
((void) data); ((void) data);
#if defined(HAVE_GETRANDOM) #if defined(HAVE_GETRANDOM)
if( has_getrandom == -1 ) ret = getrandom_wrapper( output, len, 0 );
has_getrandom = ( check_version_3_17_plus() == 0 ); if( ret >= 0 )
if( has_getrandom )
{ {
int ret;
if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
*olen = ret; *olen = ret;
return( 0 ); return( 0 );
} }
else if( errno != ENOSYS )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
/* Fall through if the system call isn't known. */
#else
((void) ret);
#endif /* HAVE_GETRANDOM */ #endif /* HAVE_GETRANDOM */
*olen = 0; *olen = 0;
......
...@@ -266,7 +266,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) ...@@ -266,7 +266,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) ) if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" ); mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) ) if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
mbedtls_snprintf( buf, buflen, "ECP - Signature is valid but shorter than the user-supplied length" ); mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) ) if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - ECP hardware accelerator failed" ); mbedtls_snprintf( buf, buflen, "ECP - ECP hardware accelerator failed" );
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
...@@ -333,7 +333,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) ...@@ -333,7 +333,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ) if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) ) if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" ); mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) ) if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" ); mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" );
#endif /* MBEDTLS_PK_C */ #endif /* MBEDTLS_PK_C */
......
...@@ -70,29 +70,56 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) ...@@ -70,29 +70,56 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
/* /*
* HMAC_DRBG update, using optional additional data (10.1.2.2) * HMAC_DRBG update, using optional additional data (10.1.2.2)
*/ */
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len ) const unsigned char *additional,
size_t add_len )
{ {
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
unsigned char sep[1]; unsigned char sep[1];
unsigned char K[MBEDTLS_MD_MAX_SIZE]; unsigned char K[MBEDTLS_MD_MAX_SIZE];
int ret;
for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
{ {
/* Step 1 or 4 */ /* Step 1 or 4 */
mbedtls_md_hmac_reset( &ctx->md_ctx ); if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); goto exit;
mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 ); if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
ctx->V, md_len ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
sep, 1 ) ) != 0 )
goto exit;
if( rounds == 2 ) if( rounds == 2 )
mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len ); {
mbedtls_md_hmac_finish( &ctx->md_ctx, K ); if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
additional, add_len ) ) != 0 )
goto exit;
}
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
goto exit;
/* Step 2 or 5 */ /* Step 2 or 5 */
mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ); if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); goto exit;
mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ); if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
ctx->V, md_len ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
goto exit;
} }
exit:
mbedtls_zeroize( K, sizeof( K ) );
return( ret );
}
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional,
size_t add_len )
{
(void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
} }
/* /*
...@@ -112,10 +139,13 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, ...@@ -112,10 +139,13 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
* Use the V memory location, which is currently all 0, to initialize the * Use the V memory location, which is currently all 0, to initialize the
* MD context with an all-zero key. Then set V to its initial value. * MD context with an all-zero key. Then set V to its initial value.
*/ */
mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) ); if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
mbedtls_md_get_size( md_info ) ) ) != 0 )
return( ret );
memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) ); memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
mbedtls_hmac_drbg_update( ctx, data, data_len ); if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
return( ret );
return( 0 ); return( 0 );
} }
...@@ -128,6 +158,7 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, ...@@ -128,6 +158,7 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
{ {
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
size_t seedlen; size_t seedlen;
int ret;
/* III. Check input length */ /* III. Check input length */
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
...@@ -139,7 +170,8 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, ...@@ -139,7 +170,8 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
/* IV. Gather entropy_len bytes of entropy for the seed */ /* IV. Gather entropy_len bytes of entropy for the seed */
if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 ) if( ( ret = ctx->f_entropy( ctx->p_entropy,
seed, ctx->entropy_len ) ) != 0 )
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
seedlen = ctx->entropy_len; seedlen = ctx->entropy_len;
...@@ -152,13 +184,16 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, ...@@ -152,13 +184,16 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
} }
/* 2. Update state */ /* 2. Update state */
mbedtls_hmac_drbg_update( ctx, seed, seedlen ); if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
goto exit;
/* 3. Reset reseed_counter */ /* 3. Reset reseed_counter */
ctx->reseed_counter = 1; ctx->reseed_counter = 1;
exit:
/* 4. Done */ /* 4. Done */
return( 0 ); mbedtls_zeroize( seed, seedlen );
return( ret );
} }
/* /*
...@@ -184,7 +219,8 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, ...@@ -184,7 +219,8 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
* Use the V memory location, which is currently all 0, to initialize the * Use the V memory location, which is currently all 0, to initialize the
* MD context with an all-zero key. Then set V to its initial value. * MD context with an all-zero key. Then set V to its initial value.
*/ */
mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ); if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
return( ret );
memset( ctx->V, 0x01, md_size ); memset( ctx->V, 0x01, md_size );
ctx->f_entropy = f_entropy; ctx->f_entropy = f_entropy;
...@@ -277,16 +313,24 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng, ...@@ -277,16 +313,24 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
/* 2. Use additional data if any */ /* 2. Use additional data if any */
if( additional != NULL && add_len != 0 ) if( additional != NULL && add_len != 0 )
mbedtls_hmac_drbg_update( ctx, additional, add_len ); {
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
additional, add_len ) ) != 0 )
goto exit;
}
/* 3, 4, 5. Generate bytes */ /* 3, 4, 5. Generate bytes */
while( left != 0 ) while( left != 0 )
{ {
size_t use_len = left > md_len ? md_len : left; size_t use_len = left > md_len ? md_len : left;
mbedtls_md_hmac_reset( &ctx->md_ctx ); if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); goto exit;
mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ); if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
ctx->V, md_len ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
goto exit;
memcpy( out, ctx->V, use_len ); memcpy( out, ctx->V, use_len );
out += use_len; out += use_len;
...@@ -294,13 +338,16 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng, ...@@ -294,13 +338,16 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
} }
/* 6. Update */ /* 6. Update */
mbedtls_hmac_drbg_update( ctx, additional, add_len ); if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
additional, add_len ) ) != 0 )
goto exit;
/* 7. Update reseed counter */ /* 7. Update reseed counter */
ctx->reseed_counter++; ctx->reseed_counter++;
exit:
/* 8. Done */ /* 8. Done */
return( 0 ); return( ret );
} }
/* /*
...@@ -392,7 +439,7 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch ...@@ -392,7 +439,7 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch
if( fread( buf, 1, n, f ) != n ) if( fread( buf, 1, n, f ) != n )
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
else else
mbedtls_hmac_drbg_update( ctx, buf, n ); ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
fclose( f ); fclose( f );
......
...@@ -115,6 +115,13 @@ int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx ) ...@@ -115,6 +115,13 @@ int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx )
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_starts( mbedtls_md2_context *ctx )
{
mbedtls_md2_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_MD2_PROCESS_ALT) #if !defined(MBEDTLS_MD2_PROCESS_ALT)
int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ) int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
{ {
...@@ -151,6 +158,13 @@ int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ) ...@@ -151,6 +158,13 @@ int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_process( mbedtls_md2_context *ctx )
{
mbedtls_internal_md2_process( ctx );
}
#endif
#endif /* !MBEDTLS_MD2_PROCESS_ALT */ #endif /* !MBEDTLS_MD2_PROCESS_ALT */
/* /*
...@@ -187,6 +201,15 @@ int mbedtls_md2_update_ret( mbedtls_md2_context *ctx, ...@@ -187,6 +201,15 @@ int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_update( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_md2_update_ret( ctx, input, ilen );
}
#endif
/* /*
* MD2 final digest * MD2 final digest
*/ */
...@@ -214,6 +237,14 @@ int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx, ...@@ -214,6 +237,14 @@ int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_finish( mbedtls_md2_context *ctx,
unsigned char output[16] )
{
mbedtls_md2_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_MD2_ALT */ #endif /* !MBEDTLS_MD2_ALT */
/* /*
...@@ -243,6 +274,15 @@ exit: ...@@ -243,6 +274,15 @@ exit:
return( ret ); return( ret );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
mbedtls_md2_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
......
...@@ -111,6 +111,13 @@ int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx ) ...@@ -111,6 +111,13 @@ int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_starts( mbedtls_md4_context *ctx )
{
mbedtls_md4_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_MD4_PROCESS_ALT) #if !defined(MBEDTLS_MD4_PROCESS_ALT)
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] ) const unsigned char data[64] )
...@@ -217,6 +224,14 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, ...@@ -217,6 +224,14 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_md4_process( ctx, data );
}
#endif
#endif /* !MBEDTLS_MD4_PROCESS_ALT */ #endif /* !MBEDTLS_MD4_PROCESS_ALT */
/* /*
...@@ -273,6 +288,15 @@ int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, ...@@ -273,6 +288,15 @@ int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_update( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_md4_update_ret( ctx, input, ilen );
}
#endif
static const unsigned char md4_padding[64] = static const unsigned char md4_padding[64] =
{ {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
...@@ -318,6 +342,14 @@ int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, ...@@ -318,6 +342,14 @@ int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_finish( mbedtls_md4_context *ctx,
unsigned char output[16] )
{
mbedtls_md4_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_MD4_ALT */ #endif /* !MBEDTLS_MD4_ALT */
/* /*
...@@ -347,6 +379,15 @@ exit: ...@@ -347,6 +379,15 @@ exit:
return( ret ); return( ret );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
mbedtls_md4_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
......
...@@ -110,6 +110,13 @@ int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx ) ...@@ -110,6 +110,13 @@ int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx )
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5_starts( mbedtls_md5_context *ctx )
{
mbedtls_md5_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_MD5_PROCESS_ALT) #if !defined(MBEDTLS_MD5_PROCESS_ALT)
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] ) const unsigned char data[64] )
...@@ -236,6 +243,14 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, ...@@ -236,6 +243,14 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_md5_process( ctx, data );
}
#endif
#endif /* !MBEDTLS_MD5_PROCESS_ALT */ #endif /* !MBEDTLS_MD5_PROCESS_ALT */
/* /*
...@@ -289,13 +304,14 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, ...@@ -289,13 +304,14 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
return( 0 ); return( 0 );
} }
static const unsigned char md5_padding[64] = #if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5_update( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen )
{ {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, mbedtls_md5_update_ret( ctx, input, ilen );
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* /*
* MD5 final digest * MD5 final digest
...@@ -304,26 +320,48 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, ...@@ -304,26 +320,48 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
unsigned char output[16] ) unsigned char output[16] )
{ {
int ret; int ret;
uint32_t last, padn; uint32_t used;
uint32_t high, low; uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 ) /*
| ( ctx->total[1] << 3 ); * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
low = ( ctx->total[0] << 3 ); */
used = ctx->total[0] & 0x3F;
PUT_UINT32_LE( low, msglen, 0 ); ctx->buffer[used++] = 0x80;
PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F; if( used <= 56 )
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); {
/* Enough room for padding + length in current block */
memset( ctx->buffer + used, 0, 56 - used );
}
else
{
/* We'll need an extra block */
memset( ctx->buffer + used, 0, 64 - used );
if( ( ret = mbedtls_md5_update_ret( ctx, md5_padding, padn ) ) != 0 ) if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret ); return( ret );
if( ( ret = mbedtls_md5_update_ret( ctx, msglen, 8 ) ) != 0 ) memset( ctx->buffer, 0, 56 );
}
/*
* Add message length
*/
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, ctx->buffer, 56 );
PUT_UINT32_LE( high, ctx->buffer, 60 );
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret ); return( ret );
/*
* Output final state
*/
PUT_UINT32_LE( ctx->state[0], output, 0 ); PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 ); PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 ); PUT_UINT32_LE( ctx->state[2], output, 8 );
...@@ -332,6 +370,14 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, ...@@ -332,6 +370,14 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5_finish( mbedtls_md5_context *ctx,
unsigned char output[16] )
{
mbedtls_md5_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_MD5_ALT */ #endif /* !MBEDTLS_MD5_ALT */
/* /*
...@@ -361,6 +407,15 @@ exit: ...@@ -361,6 +407,15 @@ exit:
return( ret ); return( ret );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
mbedtls_md5_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* RFC 1321 test vectors * RFC 1321 test vectors
......
...@@ -182,9 +182,9 @@ static int verify_header( memory_header *hdr ) ...@@ -182,9 +182,9 @@ static int verify_header( memory_header *hdr )
static int verify_chain() static int verify_chain()
{ {
memory_header *prv = heap.first, *cur = heap.first->next; memory_header *prv = heap.first, *cur;
if( verify_header( heap.first ) != 0 ) if( prv == NULL || verify_header( prv ) != 0 )
{ {
#if defined(MBEDTLS_MEMORY_DEBUG) #if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: verification of first header " mbedtls_fprintf( stderr, "FATAL: verification of first header "
...@@ -202,6 +202,8 @@ static int verify_chain() ...@@ -202,6 +202,8 @@ static int verify_chain()
return( 1 ); return( 1 );
} }
cur = heap.first->next;
while( cur != NULL ) while( cur != NULL )
{ {
if( verify_header( cur ) != 0 ) if( verify_header( cur ) != 0 )
...@@ -245,7 +247,9 @@ static void *buffer_alloc_calloc( size_t n, size_t size ) ...@@ -245,7 +247,9 @@ static void *buffer_alloc_calloc( size_t n, size_t size )
original_len = len = n * size; original_len = len = n * size;
if( n != 0 && len / n != size ) if( n == 0 || size == 0 || len / n != size )
return( NULL );
else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE )
return( NULL ); return( NULL );
if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
...@@ -386,7 +390,7 @@ static void buffer_alloc_free( void *ptr ) ...@@ -386,7 +390,7 @@ static void buffer_alloc_free( void *ptr )
if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
return; return;
if( p < heap.buf || p > heap.buf + heap.len ) if( p < heap.buf || p >= heap.buf + heap.len )
{ {
#if defined(MBEDTLS_MEMORY_DEBUG) #if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed " mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
...@@ -518,7 +522,9 @@ void mbedtls_memory_buffer_alloc_status() ...@@ -518,7 +522,9 @@ void mbedtls_memory_buffer_alloc_status()
heap.alloc_count, heap.free_count ); heap.alloc_count, heap.free_count );
if( heap.first->next == NULL ) if( heap.first->next == NULL )
{
mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
}
else else
{ {
mbedtls_fprintf( stderr, "Memory currently allocated:\n" ); mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
...@@ -570,8 +576,7 @@ static void buffer_alloc_free_mutexed( void *ptr ) ...@@ -570,8 +576,7 @@ static void buffer_alloc_free_mutexed( void *ptr )
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
{ {
memset( &heap, 0, sizeof(buffer_alloc_ctx) ); memset( &heap, 0, sizeof( buffer_alloc_ctx ) );
memset( buf, 0, len );
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &heap.mutex ); mbedtls_mutex_init( &heap.mutex );
...@@ -581,20 +586,24 @@ void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) ...@@ -581,20 +586,24 @@ void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free ); mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
#endif #endif
if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE )
return;
else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
{ {
/* Adjust len first since buf is used in the computation */ /* Adjust len first since buf is used in the computation */
len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
- (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
- (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
} }
memset( buf, 0, len );
heap.buf = buf; heap.buf = buf;
heap.len = len; heap.len = len;
heap.first = (memory_header *) buf; heap.first = (memory_header *)buf;
heap.first->size = len - sizeof(memory_header); heap.first->size = len - sizeof( memory_header );
heap.first->magic1 = MAGIC1; heap.first->magic1 = MAGIC1;
heap.first->magic2 = MAGIC2; heap.first->magic2 = MAGIC2;
heap.first_free = heap.first; heap.first_free = heap.first;
......
...@@ -625,6 +625,51 @@ static const oid_md_alg_t oid_md_alg[] = ...@@ -625,6 +625,51 @@ static const oid_md_alg_t oid_md_alg[] =
FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg) FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg)
FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg) FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg)
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg) FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg)
/*
* For HMAC digestAlgorithm
*/
typedef struct {
mbedtls_oid_descriptor_t descriptor;
mbedtls_md_type_t md_hmac;
} oid_md_hmac_t;
static const oid_md_hmac_t oid_md_hmac[] =
{
#if defined(MBEDTLS_SHA1_C)
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" },
MBEDTLS_MD_SHA1,
},
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" },
MBEDTLS_MD_SHA224,
},
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" },
MBEDTLS_MD_SHA256,
},
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" },
MBEDTLS_MD_SHA384,
},
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" },
MBEDTLS_MD_SHA512,
},
#endif /* MBEDTLS_SHA512_C */
{
{ NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE,
},
};
FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac)
FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac)
#endif /* MBEDTLS_MD_C */ #endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PKCS12_C) #if defined(MBEDTLS_PKCS12_C)
......
...@@ -442,7 +442,7 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer, ...@@ -442,7 +442,7 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
unsigned char *buf, size_t buf_len, size_t *olen ) unsigned char *buf, size_t buf_len, size_t *olen )
{ {
int ret; int ret;
unsigned char *encode_buf, *c, *p = buf; unsigned char *encode_buf = NULL, *c, *p = buf;
size_t len = 0, use_len, add_len = 0; size_t len = 0, use_len, add_len = 0;
mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len ); mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len );
...@@ -454,7 +454,8 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer, ...@@ -454,7 +454,8 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
} }
if( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) if( use_len != 0 &&
( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) )
return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data, if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data,
......
...@@ -93,6 +93,11 @@ static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, ...@@ -93,6 +93,11 @@ static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
(unsigned int) hash_len, hash, sig ) ) != 0 ) (unsigned int) hash_len, hash, sig ) ) != 0 )
return( ret ); return( ret );
/* The buffer contains a valid signature followed by extra data.
* We have a special error code for that so that so that callers can
* use mbedtls_pk_verify() to check "Does the buffer start with a
* valid signature?" and not just "Does the buffer contain a valid
* signature?". */
if( sig_len > rsa_len ) if( sig_len > rsa_len )
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
......
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