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
...@@ -97,7 +97,7 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst, ...@@ -97,7 +97,7 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
/* /*
* SHA-1 context setup * SHA-1 context setup
*/ */
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
{ {
ctx->total[0] = 0; ctx->total[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
...@@ -107,10 +107,13 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) ...@@ -107,10 +107,13 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
ctx->state[2] = 0x98BADCFE; ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476; ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0; ctx->state[4] = 0xC3D2E1F0;
return( 0 );
} }
#if !defined(MBEDTLS_SHA1_PROCESS_ALT) #if !defined(MBEDTLS_SHA1_PROCESS_ALT)
void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
const unsigned char data[64] )
{ {
uint32_t temp, W[16], A, B, C, D, E; uint32_t temp, W[16], A, B, C, D, E;
...@@ -264,19 +267,24 @@ void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[6 ...@@ -264,19 +267,24 @@ void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[6
ctx->state[2] += C; ctx->state[2] += C;
ctx->state[3] += D; ctx->state[3] += D;
ctx->state[4] += E; ctx->state[4] += E;
return( 0 );
} }
#endif /* !MBEDTLS_SHA1_PROCESS_ALT */ #endif /* !MBEDTLS_SHA1_PROCESS_ALT */
/* /*
* SHA-1 process buffer * SHA-1 process buffer
*/ */
void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
const unsigned char *input,
size_t ilen )
{ {
int ret;
size_t fill; size_t fill;
uint32_t left; uint32_t left;
if( ilen == 0 ) if( ilen == 0 )
return; return( 0 );
left = ctx->total[0] & 0x3F; left = ctx->total[0] & 0x3F;
fill = 64 - left; fill = 64 - left;
...@@ -290,7 +298,10 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, ...@@ -290,7 +298,10 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input,
if( left && ilen >= fill ) if( left && ilen >= fill )
{ {
memcpy( (void *) (ctx->buffer + left), input, fill ); memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha1_process( ctx, ctx->buffer );
if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
input += fill; input += fill;
ilen -= fill; ilen -= fill;
left = 0; left = 0;
...@@ -298,13 +309,17 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, ...@@ -298,13 +309,17 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input,
while( ilen >= 64 ) while( ilen >= 64 )
{ {
mbedtls_sha1_process( ctx, input ); if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 )
return( ret );
input += 64; input += 64;
ilen -= 64; ilen -= 64;
} }
if( ilen > 0 ) if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen ); memcpy( (void *) (ctx->buffer + left), input, ilen );
return( 0 );
} }
static const unsigned char sha1_padding[64] = static const unsigned char sha1_padding[64] =
...@@ -318,8 +333,10 @@ static const unsigned char sha1_padding[64] = ...@@ -318,8 +333,10 @@ static const unsigned char sha1_padding[64] =
/* /*
* SHA-1 final digest * SHA-1 final digest
*/ */
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
unsigned char output[20] )
{ {
int ret;
uint32_t last, padn; uint32_t last, padn;
uint32_t high, low; uint32_t high, low;
unsigned char msglen[8]; unsigned char msglen[8];
...@@ -334,14 +351,18 @@ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) ...@@ -334,14 +351,18 @@ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
last = ctx->total[0] & 0x3F; last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha1_update( ctx, sha1_padding, padn ); if( ( ret = mbedtls_sha1_update_ret( ctx, sha1_padding, padn ) ) != 0 )
mbedtls_sha1_update( ctx, msglen, 8 ); return( ret );
if( ( ret = mbedtls_sha1_update_ret( ctx, msglen, 8 ) ) != 0 )
return( ret );
PUT_UINT32_BE( ctx->state[0], output, 0 ); PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 ); PUT_UINT32_BE( ctx->state[1], output, 4 );
PUT_UINT32_BE( ctx->state[2], output, 8 ); PUT_UINT32_BE( ctx->state[2], output, 8 );
PUT_UINT32_BE( ctx->state[3], output, 12 ); PUT_UINT32_BE( ctx->state[3], output, 12 );
PUT_UINT32_BE( ctx->state[4], output, 16 ); PUT_UINT32_BE( ctx->state[4], output, 16 );
return( 0 );
} }
#endif /* !MBEDTLS_SHA1_ALT */ #endif /* !MBEDTLS_SHA1_ALT */
...@@ -349,15 +370,28 @@ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) ...@@ -349,15 +370,28 @@ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
/* /*
* output = SHA-1( input buffer ) * output = SHA-1( input buffer )
*/ */
void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) int mbedtls_sha1_ret( const unsigned char *input,
size_t ilen,
unsigned char output[20] )
{ {
int ret;
mbedtls_sha1_context ctx; mbedtls_sha1_context ctx;
mbedtls_sha1_init( &ctx ); mbedtls_sha1_init( &ctx );
mbedtls_sha1_starts( &ctx );
mbedtls_sha1_update( &ctx, input, ilen ); if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
mbedtls_sha1_finish( &ctx, output ); goto exit;
if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_sha1_free( &ctx ); mbedtls_sha1_free( &ctx );
return( ret );
} }
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
...@@ -371,7 +405,7 @@ static const unsigned char sha1_test_buf[3][57] = ...@@ -371,7 +405,7 @@ static const unsigned char sha1_test_buf[3][57] =
{ "" } { "" }
}; };
static const int sha1_test_buflen[3] = static const size_t sha1_test_buflen[3] =
{ {
3, 56, 1000 3, 56, 1000
}; };
...@@ -406,28 +440,35 @@ int mbedtls_sha1_self_test( int verbose ) ...@@ -406,28 +440,35 @@ int mbedtls_sha1_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); mbedtls_printf( " SHA-1 test #%d: ", i + 1 );
mbedtls_sha1_starts( &ctx ); if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
goto fail;
if( i == 2 ) if( i == 2 )
{ {
memset( buf, 'a', buflen = 1000 ); memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ ) for( j = 0; j < 1000; j++ )
mbedtls_sha1_update( &ctx, buf, buflen ); {
ret = mbedtls_sha1_update_ret( &ctx, buf, buflen );
if( ret != 0 )
goto fail;
}
} }
else else
mbedtls_sha1_update( &ctx, sha1_test_buf[i], {
sha1_test_buflen[i] ); ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i],
sha1_test_buflen[i] );
if( ret != 0 )
goto fail;
}
mbedtls_sha1_finish( &ctx, sha1sum ); if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 )
goto fail;
if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1; ret = 1;
goto exit; goto fail;
} }
if( verbose != 0 ) if( verbose != 0 )
...@@ -437,6 +478,12 @@ int mbedtls_sha1_self_test( int verbose ) ...@@ -437,6 +478,12 @@ int mbedtls_sha1_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
goto exit;
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
exit: exit:
mbedtls_sha1_free( &ctx ); mbedtls_sha1_free( &ctx );
......
...@@ -100,7 +100,7 @@ void mbedtls_sha256_clone( mbedtls_sha256_context *dst, ...@@ -100,7 +100,7 @@ void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
/* /*
* SHA-256 context setup * SHA-256 context setup
*/ */
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 ) int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
{ {
ctx->total[0] = 0; ctx->total[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
...@@ -131,6 +131,8 @@ void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 ) ...@@ -131,6 +131,8 @@ void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
} }
ctx->is224 = is224; ctx->is224 = is224;
return( 0 );
} }
#if !defined(MBEDTLS_SHA256_PROCESS_ALT) #if !defined(MBEDTLS_SHA256_PROCESS_ALT)
...@@ -179,7 +181,8 @@ static const uint32_t K[] = ...@@ -179,7 +181,8 @@ static const uint32_t K[] =
d += temp1; h = temp1 + temp2; \ d += temp1; h = temp1 + temp2; \
} }
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
const unsigned char data[64] )
{ {
uint32_t temp1, temp2, W[64]; uint32_t temp1, temp2, W[64];
uint32_t A[8]; uint32_t A[8];
...@@ -232,20 +235,24 @@ void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char da ...@@ -232,20 +235,24 @@ void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char da
for( i = 0; i < 8; i++ ) for( i = 0; i < 8; i++ )
ctx->state[i] += A[i]; ctx->state[i] += A[i];
return( 0 );
} }
#endif /* !MBEDTLS_SHA256_PROCESS_ALT */ #endif /* !MBEDTLS_SHA256_PROCESS_ALT */
/* /*
* SHA-256 process buffer * SHA-256 process buffer
*/ */
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input, int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
size_t ilen ) const unsigned char *input,
size_t ilen )
{ {
int ret;
size_t fill; size_t fill;
uint32_t left; uint32_t left;
if( ilen == 0 ) if( ilen == 0 )
return; return( 0 );
left = ctx->total[0] & 0x3F; left = ctx->total[0] & 0x3F;
fill = 64 - left; fill = 64 - left;
...@@ -259,7 +266,10 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *in ...@@ -259,7 +266,10 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *in
if( left && ilen >= fill ) if( left && ilen >= fill )
{ {
memcpy( (void *) (ctx->buffer + left), input, fill ); memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha256_process( ctx, ctx->buffer );
if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
input += fill; input += fill;
ilen -= fill; ilen -= fill;
left = 0; left = 0;
...@@ -267,13 +277,17 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *in ...@@ -267,13 +277,17 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *in
while( ilen >= 64 ) while( ilen >= 64 )
{ {
mbedtls_sha256_process( ctx, input ); if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
return( ret );
input += 64; input += 64;
ilen -= 64; ilen -= 64;
} }
if( ilen > 0 ) if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen ); memcpy( (void *) (ctx->buffer + left), input, ilen );
return( 0 );
} }
static const unsigned char sha256_padding[64] = static const unsigned char sha256_padding[64] =
...@@ -287,8 +301,10 @@ static const unsigned char sha256_padding[64] = ...@@ -287,8 +301,10 @@ static const unsigned char sha256_padding[64] =
/* /*
* SHA-256 final digest * SHA-256 final digest
*/ */
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] ) int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
unsigned char output[32] )
{ {
int ret;
uint32_t last, padn; uint32_t last, padn;
uint32_t high, low; uint32_t high, low;
unsigned char msglen[8]; unsigned char msglen[8];
...@@ -303,8 +319,11 @@ void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32 ...@@ -303,8 +319,11 @@ void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32
last = ctx->total[0] & 0x3F; last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha256_update( ctx, sha256_padding, padn ); if( ( ret = mbedtls_sha256_update_ret( ctx, sha256_padding, padn ) ) != 0 )
mbedtls_sha256_update( ctx, msglen, 8 ); return( ret );
if( ( ret = mbedtls_sha256_update_ret( ctx, msglen, 8 ) ) != 0 )
return( ret );
PUT_UINT32_BE( ctx->state[0], output, 0 ); PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 ); PUT_UINT32_BE( ctx->state[1], output, 4 );
...@@ -316,6 +335,8 @@ void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32 ...@@ -316,6 +335,8 @@ void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32
if( ctx->is224 == 0 ) if( ctx->is224 == 0 )
PUT_UINT32_BE( ctx->state[7], output, 28 ); PUT_UINT32_BE( ctx->state[7], output, 28 );
return( 0 );
} }
#endif /* !MBEDTLS_SHA256_ALT */ #endif /* !MBEDTLS_SHA256_ALT */
...@@ -323,16 +344,29 @@ void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32 ...@@ -323,16 +344,29 @@ void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32
/* /*
* output = SHA-256( input buffer ) * output = SHA-256( input buffer )
*/ */
void mbedtls_sha256( const unsigned char *input, size_t ilen, int mbedtls_sha256_ret( const unsigned char *input,
unsigned char output[32], int is224 ) size_t ilen,
unsigned char output[32],
int is224 )
{ {
int ret;
mbedtls_sha256_context ctx; mbedtls_sha256_context ctx;
mbedtls_sha256_init( &ctx ); mbedtls_sha256_init( &ctx );
mbedtls_sha256_starts( &ctx, is224 );
mbedtls_sha256_update( &ctx, input, ilen ); if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
mbedtls_sha256_finish( &ctx, output ); goto exit;
if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_sha256_free( &ctx ); mbedtls_sha256_free( &ctx );
return( ret );
} }
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
...@@ -346,7 +380,7 @@ static const unsigned char sha256_test_buf[3][57] = ...@@ -346,7 +380,7 @@ static const unsigned char sha256_test_buf[3][57] =
{ "" } { "" }
}; };
static const int sha256_test_buflen[3] = static const size_t sha256_test_buflen[3] =
{ {
3, 56, 1000 3, 56, 1000
}; };
...@@ -415,28 +449,37 @@ int mbedtls_sha256_self_test( int verbose ) ...@@ -415,28 +449,37 @@ int mbedtls_sha256_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
mbedtls_sha256_starts( &ctx, k ); if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
goto fail;
if( j == 2 ) if( j == 2 )
{ {
memset( buf, 'a', buflen = 1000 ); memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ ) for( j = 0; j < 1000; j++ )
mbedtls_sha256_update( &ctx, buf, buflen ); {
ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
if( ret != 0 )
goto fail;
}
} }
else else
mbedtls_sha256_update( &ctx, sha256_test_buf[j], {
sha256_test_buflen[j] ); ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
sha256_test_buflen[j] );
if( ret != 0 )
goto fail;
}
if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
goto fail;
mbedtls_sha256_finish( &ctx, sha256sum );
if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1; ret = 1;
goto exit; goto fail;
} }
if( verbose != 0 ) if( verbose != 0 )
...@@ -446,6 +489,12 @@ int mbedtls_sha256_self_test( int verbose ) ...@@ -446,6 +489,12 @@ int mbedtls_sha256_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
goto exit;
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
exit: exit:
mbedtls_sha256_free( &ctx ); mbedtls_sha256_free( &ctx );
mbedtls_free( buf ); mbedtls_free( buf );
......
...@@ -114,7 +114,7 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst, ...@@ -114,7 +114,7 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
/* /*
* SHA-512 context setup * SHA-512 context setup
*/ */
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 ) int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
{ {
ctx->total[0] = 0; ctx->total[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
...@@ -145,6 +145,8 @@ void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 ) ...@@ -145,6 +145,8 @@ void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
} }
ctx->is384 = is384; ctx->is384 = is384;
return( 0 );
} }
#if !defined(MBEDTLS_SHA512_PROCESS_ALT) #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
...@@ -196,7 +198,8 @@ static const uint64_t K[80] = ...@@ -196,7 +198,8 @@ static const uint64_t K[80] =
UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
}; };
void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
const unsigned char data[128] )
{ {
int i; int i;
uint64_t temp1, temp2, W[80]; uint64_t temp1, temp2, W[80];
...@@ -263,20 +266,24 @@ void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char da ...@@ -263,20 +266,24 @@ void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char da
ctx->state[5] += F; ctx->state[5] += F;
ctx->state[6] += G; ctx->state[6] += G;
ctx->state[7] += H; ctx->state[7] += H;
return( 0 );
} }
#endif /* !MBEDTLS_SHA512_PROCESS_ALT */ #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
/* /*
* SHA-512 process buffer * SHA-512 process buffer
*/ */
void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input, int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
size_t ilen ) const unsigned char *input,
size_t ilen )
{ {
int ret;
size_t fill; size_t fill;
unsigned int left; unsigned int left;
if( ilen == 0 ) if( ilen == 0 )
return; return( 0 );
left = (unsigned int) (ctx->total[0] & 0x7F); left = (unsigned int) (ctx->total[0] & 0x7F);
fill = 128 - left; fill = 128 - left;
...@@ -289,7 +296,10 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *in ...@@ -289,7 +296,10 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *in
if( left && ilen >= fill ) if( left && ilen >= fill )
{ {
memcpy( (void *) (ctx->buffer + left), input, fill ); memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha512_process( ctx, ctx->buffer );
if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
input += fill; input += fill;
ilen -= fill; ilen -= fill;
left = 0; left = 0;
...@@ -297,13 +307,17 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *in ...@@ -297,13 +307,17 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *in
while( ilen >= 128 ) while( ilen >= 128 )
{ {
mbedtls_sha512_process( ctx, input ); if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
return( ret );
input += 128; input += 128;
ilen -= 128; ilen -= 128;
} }
if( ilen > 0 ) if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen ); memcpy( (void *) (ctx->buffer + left), input, ilen );
return( 0 );
} }
static const unsigned char sha512_padding[128] = static const unsigned char sha512_padding[128] =
...@@ -321,8 +335,10 @@ static const unsigned char sha512_padding[128] = ...@@ -321,8 +335,10 @@ static const unsigned char sha512_padding[128] =
/* /*
* SHA-512 final digest * SHA-512 final digest
*/ */
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] ) int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
unsigned char output[64] )
{ {
int ret;
size_t last, padn; size_t last, padn;
uint64_t high, low; uint64_t high, low;
unsigned char msglen[16]; unsigned char msglen[16];
...@@ -337,8 +353,11 @@ void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64 ...@@ -337,8 +353,11 @@ void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64
last = (size_t)( ctx->total[0] & 0x7F ); last = (size_t)( ctx->total[0] & 0x7F );
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
mbedtls_sha512_update( ctx, sha512_padding, padn ); if( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 )
mbedtls_sha512_update( ctx, msglen, 16 ); return( ret );
if( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 )
return( ret );
PUT_UINT64_BE( ctx->state[0], output, 0 ); PUT_UINT64_BE( ctx->state[0], output, 0 );
PUT_UINT64_BE( ctx->state[1], output, 8 ); PUT_UINT64_BE( ctx->state[1], output, 8 );
...@@ -352,6 +371,8 @@ void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64 ...@@ -352,6 +371,8 @@ void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64
PUT_UINT64_BE( ctx->state[6], output, 48 ); PUT_UINT64_BE( ctx->state[6], output, 48 );
PUT_UINT64_BE( ctx->state[7], output, 56 ); PUT_UINT64_BE( ctx->state[7], output, 56 );
} }
return( 0 );
} }
#endif /* !MBEDTLS_SHA512_ALT */ #endif /* !MBEDTLS_SHA512_ALT */
...@@ -359,16 +380,29 @@ void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64 ...@@ -359,16 +380,29 @@ void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64
/* /*
* output = SHA-512( input buffer ) * output = SHA-512( input buffer )
*/ */
void mbedtls_sha512( const unsigned char *input, size_t ilen, int mbedtls_sha512_ret( const unsigned char *input,
unsigned char output[64], int is384 ) size_t ilen,
unsigned char output[64],
int is384 )
{ {
int ret;
mbedtls_sha512_context ctx; mbedtls_sha512_context ctx;
mbedtls_sha512_init( &ctx ); mbedtls_sha512_init( &ctx );
mbedtls_sha512_starts( &ctx, is384 );
mbedtls_sha512_update( &ctx, input, ilen ); if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
mbedtls_sha512_finish( &ctx, output ); goto exit;
if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_sha512_free( &ctx ); mbedtls_sha512_free( &ctx );
return( ret );
} }
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
...@@ -384,7 +418,7 @@ static const unsigned char sha512_test_buf[3][113] = ...@@ -384,7 +418,7 @@ static const unsigned char sha512_test_buf[3][113] =
{ "" } { "" }
}; };
static const int sha512_test_buflen[3] = static const size_t sha512_test_buflen[3] =
{ {
3, 112, 1000 3, 112, 1000
}; };
...@@ -471,28 +505,35 @@ int mbedtls_sha512_self_test( int verbose ) ...@@ -471,28 +505,35 @@ int mbedtls_sha512_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
mbedtls_sha512_starts( &ctx, k ); if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
goto fail;
if( j == 2 ) if( j == 2 )
{ {
memset( buf, 'a', buflen = 1000 ); memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ ) for( j = 0; j < 1000; j++ )
mbedtls_sha512_update( &ctx, buf, buflen ); {
ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
if( ret != 0 )
goto fail;
}
} }
else else
mbedtls_sha512_update( &ctx, sha512_test_buf[j], {
sha512_test_buflen[j] ); ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
sha512_test_buflen[j] );
if( ret != 0 )
goto fail;
}
mbedtls_sha512_finish( &ctx, sha512sum ); if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
goto fail;
if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1; ret = 1;
goto exit; goto fail;
} }
if( verbose != 0 ) if( verbose != 0 )
...@@ -502,6 +543,12 @@ int mbedtls_sha512_self_test( int verbose ) ...@@ -502,6 +543,12 @@ int mbedtls_sha512_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
goto exit;
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
exit: exit:
mbedtls_sha512_free( &ctx ); mbedtls_sha512_free( &ctx );
mbedtls_free( buf ); mbedtls_free( buf );
......
...@@ -321,6 +321,7 @@ void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ) ...@@ -321,6 +321,7 @@ void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &cache->mutex ); mbedtls_mutex_free( &cache->mutex );
#endif #endif
cache->chain = NULL;
} }
#endif /* MBEDTLS_SSL_CACHE_C */ #endif /* MBEDTLS_SSL_CACHE_C */
...@@ -80,6 +80,13 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, ...@@ -80,6 +80,13 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
} }
/* /*
* Sect. 3, RFC 6066 (TLS Extensions Definitions)
*
* In order to provide any of the server names, clients MAY include an
* extension of type "server_name" in the (extended) client hello. The
* "extension_data" field of this extension SHALL contain
* "ServerNameList" where:
*
* struct { * struct {
* NameType name_type; * NameType name_type;
* select (name_type) { * select (name_type) {
...@@ -96,6 +103,7 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, ...@@ -96,6 +103,7 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
* struct { * struct {
* ServerName server_name_list<1..2^16-1> * ServerName server_name_list<1..2^16-1>
* } ServerNameList; * } ServerNameList;
*
*/ */
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
...@@ -126,6 +134,9 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, ...@@ -126,6 +134,9 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
*olen = 0; *olen = 0;
/* We're always including an TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the
* initial ClientHello, in which case also adding the renegotiation
* info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */
if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
return; return;
...@@ -963,6 +974,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ...@@ -963,6 +974,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen; ext_len += olen;
#endif #endif
/* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added
* even if MBEDTLS_SSL_RENEGOTIATION is not defined. */
#if defined(MBEDTLS_SSL_RENEGOTIATION) #if defined(MBEDTLS_SSL_RENEGOTIATION)
ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
...@@ -1440,9 +1453,6 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ...@@ -1440,9 +1453,6 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
#endif #endif
int handshake_failure = 0; int handshake_failure = 0;
const mbedtls_ssl_ciphersuite_t *suite_info; const mbedtls_ssl_ciphersuite_t *suite_info;
#if defined(MBEDTLS_DEBUG_C)
uint32_t t;
#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
...@@ -1545,13 +1555,11 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ...@@ -1545,13 +1555,11 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
} }
#if defined(MBEDTLS_DEBUG_C) MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu",
t = ( (uint32_t) buf[2] << 24 ) ( (uint32_t) buf[2] << 24 ) |
| ( (uint32_t) buf[3] << 16 ) ( (uint32_t) buf[3] << 16 ) |
| ( (uint32_t) buf[4] << 8 ) ( (uint32_t) buf[4] << 8 ) |
| ( (uint32_t) buf[5] ); ( (uint32_t) buf[5] ) ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
#endif
memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 ); memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
...@@ -2258,7 +2266,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2258,7 +2266,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
int ret; int ret;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info; ssl->transform_negotiate->ciphersuite_info;
unsigned char *p, *end; unsigned char *p = NULL, *end = NULL;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
...@@ -2490,39 +2498,11 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2490,39 +2498,11 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
defined(MBEDTLS_SSL_PROTO_TLS1_1) defined(MBEDTLS_SSL_PROTO_TLS1_1)
if( md_alg == MBEDTLS_MD_NONE ) if( md_alg == MBEDTLS_MD_NONE )
{ {
mbedtls_md5_context mbedtls_md5;
mbedtls_sha1_context mbedtls_sha1;
mbedtls_md5_init( &mbedtls_md5 );
mbedtls_sha1_init( &mbedtls_sha1 );
hashlen = 36; hashlen = 36;
ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, params,
/* params_len );
* digitally-signed struct { if( ret != 0 )
* opaque md5_hash[16]; return( ret );
* opaque sha_hash[20];
* };
*
* md5_hash
* MD5(ClientHello.random + ServerHello.random
* + ServerParams);
* sha_hash
* SHA(ClientHello.random + ServerHello.random
* + ServerParams);
*/
mbedtls_md5_starts( &mbedtls_md5 );
mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
mbedtls_md5_update( &mbedtls_md5, params, params_len );
mbedtls_md5_finish( &mbedtls_md5, hash );
mbedtls_sha1_starts( &mbedtls_sha1 );
mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
mbedtls_md5_free( &mbedtls_md5 );
mbedtls_sha1_free( &mbedtls_sha1 );
} }
else else
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
...@@ -2531,34 +2511,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2531,34 +2511,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
defined(MBEDTLS_SSL_PROTO_TLS1_2) defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( md_alg != MBEDTLS_MD_NONE ) if( md_alg != MBEDTLS_MD_NONE )
{ {
mbedtls_md_context_t ctx;
mbedtls_md_init( &ctx );
/* Info from md_alg will be used instead */ /* Info from md_alg will be used instead */
hashlen = 0; hashlen = 0;
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, params,
/* params_len, md_alg );
* digitally-signed struct { if( ret != 0 )
* opaque client_random[32];
* opaque server_random[32];
* ServerDHParams params;
* };
*/
if( ( ret = mbedtls_md_setup( &ctx,
mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( ret ); return( ret );
}
mbedtls_md_starts( &ctx );
mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
mbedtls_md_update( &ctx, params, params_len );
mbedtls_md_finish( &ctx, hash );
mbedtls_md_free( &ctx );
} }
else else
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
......
...@@ -603,33 +603,41 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, ...@@ -603,33 +603,41 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
} }
/* /*
* Use our order of preference * Validate peer's list (lengths)
*/ */
start = buf + 2; start = buf + 2;
end = buf + len; end = buf + len;
for( theirs = start; theirs != end; theirs += cur_len )
{
cur_len = *theirs++;
/* Current identifier must fit in list */
if( cur_len > (size_t)( end - theirs ) )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
/* Empty strings MUST NOT be included */
if( cur_len == 0 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
}
/*
* Use our order of preference
*/
for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ ) for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ )
{ {
ours_len = strlen( *ours ); ours_len = strlen( *ours );
for( theirs = start; theirs != end; theirs += cur_len ) for( theirs = start; theirs != end; theirs += cur_len )
{ {
/* If the list is well formed, we should get equality first */
if( theirs > end )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
cur_len = *theirs++; cur_len = *theirs++;
/* Empty strings MUST NOT be included */
if( cur_len == 0 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
if( cur_len == ours_len && if( cur_len == ours_len &&
memcmp( theirs, *ours, cur_len ) == 0 ) memcmp( theirs, *ours, cur_len ) == 0 )
{ {
...@@ -2042,7 +2050,7 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, ...@@ -2042,7 +2050,7 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t *suite = NULL; const mbedtls_ssl_ciphersuite_t *suite = NULL;
const mbedtls_cipher_info_t *cipher = NULL; const mbedtls_cipher_info_t *cipher = NULL;
if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_EXTENDED_MS_DISABLED || if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
*olen = 0; *olen = 0;
...@@ -2937,10 +2945,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2937,10 +2945,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
* opaque dh_Ys<1..2^16-1>; * opaque dh_Ys<1..2^16-1>;
* } ServerDHParams; * } ServerDHParams;
*/ */
if( ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->conf->dhm_P ) ) != 0 || if( ( ret = mbedtls_dhm_set_group( &ssl->handshake->dhm_ctx,
( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->conf->dhm_G ) ) != 0 ) &ssl->conf->dhm_P,
&ssl->conf->dhm_G ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_copy", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_set_group", ret );
return( ret ); return( ret );
} }
...@@ -3093,40 +3102,12 @@ curve_matching_done: ...@@ -3093,40 +3102,12 @@ curve_matching_done:
defined(MBEDTLS_SSL_PROTO_TLS1_1) defined(MBEDTLS_SSL_PROTO_TLS1_1)
if( md_alg == MBEDTLS_MD_NONE ) if( md_alg == MBEDTLS_MD_NONE )
{ {
mbedtls_md5_context mbedtls_md5;
mbedtls_sha1_context mbedtls_sha1;
mbedtls_md5_init( &mbedtls_md5 );
mbedtls_sha1_init( &mbedtls_sha1 );
/*
* digitally-signed struct {
* opaque md5_hash[16];
* opaque sha_hash[20];
* };
*
* md5_hash
* MD5(ClientHello.random + ServerHello.random
* + ServerParams);
* sha_hash
* SHA(ClientHello.random + ServerHello.random
* + ServerParams);
*/
mbedtls_md5_starts( &mbedtls_md5 );
mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
mbedtls_md5_update( &mbedtls_md5, dig_signed, dig_signed_len );
mbedtls_md5_finish( &mbedtls_md5, hash );
mbedtls_sha1_starts( &mbedtls_sha1 );
mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
mbedtls_sha1_update( &mbedtls_sha1, dig_signed, dig_signed_len );
mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
hashlen = 36; hashlen = 36;
ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash,
mbedtls_md5_free( &mbedtls_md5 ); dig_signed,
mbedtls_sha1_free( &mbedtls_sha1 ); dig_signed_len );
if( ret != 0 )
return( ret );
} }
else else
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
...@@ -3135,32 +3116,14 @@ curve_matching_done: ...@@ -3135,32 +3116,14 @@ curve_matching_done:
defined(MBEDTLS_SSL_PROTO_TLS1_2) defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( md_alg != MBEDTLS_MD_NONE ) if( md_alg != MBEDTLS_MD_NONE )
{ {
mbedtls_md_context_t ctx;
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
mbedtls_md_init( &ctx );
/* Info from md_alg will be used instead */ /* Info from md_alg will be used instead */
hashlen = 0; hashlen = 0;
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash,
/* dig_signed,
* digitally-signed struct { dig_signed_len,
* opaque client_random[32]; md_alg );
* opaque server_random[32]; if( ret != 0 )
* ServerDHParams params;
* };
*/
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
return( ret ); return( ret );
}
mbedtls_md_starts( &ctx );
mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
mbedtls_md_update( &ctx, dig_signed, dig_signed_len );
mbedtls_md_finish( &ctx, hash );
mbedtls_md_free( &ctx );
} }
else else
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
...@@ -3433,7 +3396,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha ...@@ -3433,7 +3396,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
/* /*
* Receive client pre-shared key identity name * Receive client pre-shared key identity name
*/ */
if( *p + 2 > end ) if( end - *p < 2 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
...@@ -3442,7 +3405,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha ...@@ -3442,7 +3405,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
n = ( (*p)[0] << 8 ) | (*p)[1]; n = ( (*p)[0] << 8 ) | (*p)[1];
*p += 2; *p += 2;
if( n < 1 || n > 65535 || *p + n > end ) if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
......
...@@ -221,6 +221,7 @@ static int ssl3_prf( const unsigned char *secret, size_t slen, ...@@ -221,6 +221,7 @@ static int ssl3_prf( const unsigned char *secret, size_t slen,
const unsigned char *random, size_t rlen, const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen ) unsigned char *dstbuf, size_t dlen )
{ {
int ret = 0;
size_t i; size_t i;
mbedtls_md5_context md5; mbedtls_md5_context md5;
mbedtls_sha1_context sha1; mbedtls_sha1_context sha1;
...@@ -243,25 +244,35 @@ static int ssl3_prf( const unsigned char *secret, size_t slen, ...@@ -243,25 +244,35 @@ static int ssl3_prf( const unsigned char *secret, size_t slen,
{ {
memset( padding, (unsigned char) ('A' + i), 1 + i ); memset( padding, (unsigned char) ('A' + i), 1 + i );
mbedtls_sha1_starts( &sha1 ); if( ( ret = mbedtls_sha1_starts_ret( &sha1 ) ) != 0 )
mbedtls_sha1_update( &sha1, padding, 1 + i ); goto exit;
mbedtls_sha1_update( &sha1, secret, slen ); if( ( ret = mbedtls_sha1_update_ret( &sha1, padding, 1 + i ) ) != 0 )
mbedtls_sha1_update( &sha1, random, rlen ); goto exit;
mbedtls_sha1_finish( &sha1, sha1sum ); if( ( ret = mbedtls_sha1_update_ret( &sha1, secret, slen ) ) != 0 )
goto exit;
mbedtls_md5_starts( &md5 ); if( ( ret = mbedtls_sha1_update_ret( &sha1, random, rlen ) ) != 0 )
mbedtls_md5_update( &md5, secret, slen ); goto exit;
mbedtls_md5_update( &md5, sha1sum, 20 ); if( ( ret = mbedtls_sha1_finish_ret( &sha1, sha1sum ) ) != 0 )
mbedtls_md5_finish( &md5, dstbuf + i * 16 ); goto exit;
}
if( ( ret = mbedtls_md5_starts_ret( &md5 ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md5_update_ret( &md5, secret, slen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md5_update_ret( &md5, sha1sum, 20 ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md5_finish_ret( &md5, dstbuf + i * 16 ) ) != 0 )
goto exit;
}
exit:
mbedtls_md5_free( &md5 ); mbedtls_md5_free( &md5 );
mbedtls_sha1_free( &sha1 ); mbedtls_sha1_free( &sha1 );
mbedtls_zeroize( padding, sizeof( padding ) ); mbedtls_zeroize( padding, sizeof( padding ) );
mbedtls_zeroize( sha1sum, sizeof( sha1sum ) ); mbedtls_zeroize( sha1sum, sizeof( sha1sum ) );
return( 0 ); return( ret );
} }
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ #endif /* MBEDTLS_SSL_PROTO_SSL3 */
...@@ -978,25 +989,25 @@ void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] ) ...@@ -978,25 +989,25 @@ void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
memset( pad_1, 0x36, 48 ); memset( pad_1, 0x36, 48 );
memset( pad_2, 0x5C, 48 ); memset( pad_2, 0x5C, 48 );
mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 ); mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 );
mbedtls_md5_update( &md5, pad_1, 48 ); mbedtls_md5_update_ret( &md5, pad_1, 48 );
mbedtls_md5_finish( &md5, hash ); mbedtls_md5_finish_ret( &md5, hash );
mbedtls_md5_starts( &md5 ); mbedtls_md5_starts_ret( &md5 );
mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 ); mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 );
mbedtls_md5_update( &md5, pad_2, 48 ); mbedtls_md5_update_ret( &md5, pad_2, 48 );
mbedtls_md5_update( &md5, hash, 16 ); mbedtls_md5_update_ret( &md5, hash, 16 );
mbedtls_md5_finish( &md5, hash ); mbedtls_md5_finish_ret( &md5, hash );
mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 ); mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 );
mbedtls_sha1_update( &sha1, pad_1, 40 ); mbedtls_sha1_update_ret( &sha1, pad_1, 40 );
mbedtls_sha1_finish( &sha1, hash + 16 ); mbedtls_sha1_finish_ret( &sha1, hash + 16 );
mbedtls_sha1_starts( &sha1 ); mbedtls_sha1_starts_ret( &sha1 );
mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 ); mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 );
mbedtls_sha1_update( &sha1, pad_2, 40 ); mbedtls_sha1_update_ret( &sha1, pad_2, 40 );
mbedtls_sha1_update( &sha1, hash + 16, 20 ); mbedtls_sha1_update_ret( &sha1, hash + 16, 20 );
mbedtls_sha1_finish( &sha1, hash + 16 ); mbedtls_sha1_finish_ret( &sha1, hash + 16 );
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
...@@ -1022,8 +1033,8 @@ void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] ) ...@@ -1022,8 +1033,8 @@ void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
mbedtls_md5_finish( &md5, hash ); mbedtls_md5_finish_ret( &md5, hash );
mbedtls_sha1_finish( &sha1, hash + 16 ); mbedtls_sha1_finish_ret( &sha1, hash + 16 );
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
...@@ -1046,7 +1057,7 @@ void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32 ...@@ -1046,7 +1057,7 @@ void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
mbedtls_sha256_finish( &sha256, hash ); mbedtls_sha256_finish_ret( &sha256, hash );
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 ); MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
...@@ -1067,7 +1078,7 @@ void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48 ...@@ -1067,7 +1078,7 @@ void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
mbedtls_sha512_finish( &sha512, hash ); mbedtls_sha512_finish_ret( &sha512, hash );
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 ); MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
...@@ -1203,9 +1214,12 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch ...@@ -1203,9 +1214,12 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
/* /*
* SSLv3.0 MAC functions * SSLv3.0 MAC functions
*/ */
static void ssl_mac( mbedtls_md_context_t *md_ctx, unsigned char *secret, #define SSL_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */
unsigned char *buf, size_t len, static void ssl_mac( mbedtls_md_context_t *md_ctx,
unsigned char *ctr, int type ) const unsigned char *secret,
const unsigned char *buf, size_t len,
const unsigned char *ctr, int type,
unsigned char out[SSL_MAC_MAX_BYTES] )
{ {
unsigned char header[11]; unsigned char header[11];
unsigned char padding[48]; unsigned char padding[48];
...@@ -1230,14 +1244,14 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx, unsigned char *secret, ...@@ -1230,14 +1244,14 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx, unsigned char *secret,
mbedtls_md_update( md_ctx, padding, padlen ); mbedtls_md_update( md_ctx, padding, padlen );
mbedtls_md_update( md_ctx, header, 11 ); mbedtls_md_update( md_ctx, header, 11 );
mbedtls_md_update( md_ctx, buf, len ); mbedtls_md_update( md_ctx, buf, len );
mbedtls_md_finish( md_ctx, buf + len ); mbedtls_md_finish( md_ctx, out );
memset( padding, 0x5C, padlen ); memset( padding, 0x5C, padlen );
mbedtls_md_starts( md_ctx ); mbedtls_md_starts( md_ctx );
mbedtls_md_update( md_ctx, secret, md_size ); mbedtls_md_update( md_ctx, secret, md_size );
mbedtls_md_update( md_ctx, padding, padlen ); mbedtls_md_update( md_ctx, padding, padlen );
mbedtls_md_update( md_ctx, buf + len, md_size ); mbedtls_md_update( md_ctx, out, md_size );
mbedtls_md_finish( md_ctx, buf + len ); mbedtls_md_finish( md_ctx, out );
} }
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ #endif /* MBEDTLS_SSL_PROTO_SSL3 */
...@@ -1268,6 +1282,14 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1268,6 +1282,14 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
ssl->out_msg, ssl->out_msglen ); ssl->out_msg, ssl->out_msglen );
if( ssl->out_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %u too large, maximum %d",
(unsigned) ssl->out_msglen,
MBEDTLS_SSL_MAX_CONTENT_LEN ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
/* /*
* Add MAC before if needed * Add MAC before if needed
*/ */
...@@ -1282,10 +1304,15 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1282,10 +1304,15 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_PROTO_SSL3) #if defined(MBEDTLS_SSL_PROTO_SSL3)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
unsigned char mac[SSL_MAC_MAX_BYTES];
ssl_mac( &ssl->transform_out->md_ctx_enc, ssl_mac( &ssl->transform_out->md_ctx_enc,
ssl->transform_out->mac_enc, ssl->transform_out->mac_enc,
ssl->out_msg, ssl->out_msglen, ssl->out_msg, ssl->out_msglen,
ssl->out_ctr, ssl->out_msgtype ); ssl->out_ctr, ssl->out_msgtype,
mac );
memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
} }
else else
#endif #endif
...@@ -1293,14 +1320,17 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1293,14 +1320,17 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
defined(MBEDTLS_SSL_PROTO_TLS1_2) defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
{ {
unsigned char mac[MBEDTLS_SSL_MAC_ADD];
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 ); mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 );
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 ); mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 );
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 ); mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 );
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
ssl->out_msg, ssl->out_msglen ); ssl->out_msg, ssl->out_msglen );
mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
ssl->out_msg + ssl->out_msglen );
mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
} }
else else
#endif #endif
...@@ -1562,8 +1592,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1562,8 +1592,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
return( 0 ); return( 0 );
} }
#define SSL_MAX_MAC_SIZE 48
static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
{ {
size_t i; size_t i;
...@@ -1731,7 +1759,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1731,7 +1759,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
{ {
unsigned char computed_mac[SSL_MAX_MAC_SIZE]; unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
unsigned char pseudo_hdr[13]; unsigned char pseudo_hdr[13];
MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
...@@ -1749,16 +1777,16 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1749,16 +1777,16 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 ); mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 );
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec,
ssl->in_iv, ssl->in_msglen ); ssl->in_iv, ssl->in_msglen );
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, computed_mac ); mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen, MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen,
ssl->transform_in->maclen ); ssl->transform_in->maclen );
MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", computed_mac, MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
ssl->transform_in->maclen ); ssl->transform_in->maclen );
if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, computed_mac, if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect,
ssl->transform_in->maclen ) != 0 ) ssl->transform_in->maclen ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
...@@ -1918,22 +1946,21 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1918,22 +1946,21 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
#if defined(SSL_SOME_MODES_USE_MAC) #if defined(SSL_SOME_MODES_USE_MAC)
if( auth_done == 0 ) if( auth_done == 0 )
{ {
unsigned char tmp[SSL_MAX_MAC_SIZE]; unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
ssl->in_msglen -= ssl->transform_in->maclen; ssl->in_msglen -= ssl->transform_in->maclen;
ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 ); ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 );
ssl->in_len[1] = (unsigned char)( ssl->in_msglen ); ssl->in_len[1] = (unsigned char)( ssl->in_msglen );
memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen );
#if defined(MBEDTLS_SSL_PROTO_SSL3) #if defined(MBEDTLS_SSL_PROTO_SSL3)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
ssl_mac( &ssl->transform_in->md_ctx_dec, ssl_mac( &ssl->transform_in->md_ctx_dec,
ssl->transform_in->mac_dec, ssl->transform_in->mac_dec,
ssl->in_msg, ssl->in_msglen, ssl->in_msg, ssl->in_msglen,
ssl->in_ctr, ssl->in_msgtype ); ssl->in_ctr, ssl->in_msgtype,
mac_expect );
} }
else else
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ #endif /* MBEDTLS_SSL_PROTO_SSL3 */
...@@ -1965,8 +1992,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1965,8 +1992,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 ); mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg, mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
ssl->in_msglen ); ssl->in_msglen );
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
ssl->in_msg + ssl->in_msglen );
/* Call mbedtls_md_process at least once due to cache attacks */ /* Call mbedtls_md_process at least once due to cache attacks */
for( j = 0; j < extra_run + 1; j++ ) for( j = 0; j < extra_run + 1; j++ )
mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg ); mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
...@@ -1981,12 +2007,12 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) ...@@ -1981,12 +2007,12 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen ); MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen, MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen,
ssl->transform_in->maclen ); ssl->transform_in->maclen );
if( mbedtls_ssl_safer_memcmp( tmp, ssl->in_msg + ssl->in_msglen, if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect,
ssl->transform_in->maclen ) != 0 ) ssl->transform_in->maclen ) != 0 )
{ {
#if defined(MBEDTLS_SSL_DEBUG_ALL) #if defined(MBEDTLS_SSL_DEBUG_ALL)
MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
...@@ -2735,6 +2761,15 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) ...@@ -2735,6 +2761,15 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{ {
/* Make room for the additional DTLS fields */ /* Make room for the additional DTLS fields */
if( MBEDTLS_SSL_MAX_CONTENT_LEN - ssl->out_msglen < 8 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
"size %u, maximum %u",
(unsigned) ( ssl->in_hslen - 4 ),
(unsigned) ( MBEDTLS_SSL_MAX_CONTENT_LEN - 12 ) ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
memmove( ssl->out_msg + 12, ssl->out_msg + 4, len - 4 ); memmove( ssl->out_msg + 12, ssl->out_msg + 4, len - 4 );
ssl->out_msglen += 8; ssl->out_msglen += 8;
len += 8; len += 8;
...@@ -3493,8 +3528,15 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) ...@@ -3493,8 +3528,15 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); #if defined(MBEDTLS_SSL_PROTO_DTLS)
/* Silently ignore invalid DTLS records as recommended by RFC 6347
* Section 4.1.2.7 */
if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
#endif /* MBEDTLS_SSL_PROTO_DTLS */
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
...@@ -3515,7 +3557,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) ...@@ -3515,7 +3557,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN
- (size_t)( ssl->in_msg - ssl->in_buf ) ) - (size_t)( ssl->in_msg - ssl->in_buf ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
...@@ -3525,7 +3567,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) ...@@ -3525,7 +3567,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
if( ssl->in_msglen < 1 || if( ssl->in_msglen < 1 ||
ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
} }
...@@ -3533,7 +3575,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) ...@@ -3533,7 +3575,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
{ {
if( ssl->in_msglen < ssl->transform_in->minlen ) if( ssl->in_msglen < ssl->transform_in->minlen )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
...@@ -3554,7 +3596,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) ...@@ -3554,7 +3596,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
ssl->in_msglen > ssl->transform_in->minlen + ssl->in_msglen > ssl->transform_in->minlen +
MBEDTLS_SSL_MAX_CONTENT_LEN + 256 ) MBEDTLS_SSL_MAX_CONTENT_LEN + 256 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
#endif #endif
...@@ -3678,7 +3720,7 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) ...@@ -3678,7 +3720,7 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl )
if( ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) if( ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
} }
...@@ -4584,7 +4626,6 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) ...@@ -4584,7 +4626,6 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ret != 0 ) if( ret != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "x509_verify_cert flags: %d", ssl->session_negotiate->verify_result ) );
MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
} }
...@@ -4837,15 +4878,15 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) ...@@ -4837,15 +4878,15 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
{ {
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) defined(MBEDTLS_SSL_PROTO_TLS1_1)
mbedtls_md5_starts( &ssl->handshake->fin_md5 ); mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 );
mbedtls_sha1_starts( &ssl->handshake->fin_sha1 ); mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 );
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C) #if defined(MBEDTLS_SHA256_C)
mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 ); mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 );
#endif #endif
#if defined(MBEDTLS_SHA512_C) #if defined(MBEDTLS_SHA512_C)
mbedtls_sha512_starts( &ssl->handshake->fin_sha512, 1 ); mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 );
#endif #endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
} }
...@@ -4855,15 +4896,15 @@ static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, ...@@ -4855,15 +4896,15 @@ static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
{ {
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) defined(MBEDTLS_SSL_PROTO_TLS1_1)
mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len ); mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len ); mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C) #if defined(MBEDTLS_SHA256_C)
mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len ); mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
#endif #endif
#if defined(MBEDTLS_SHA512_C) #if defined(MBEDTLS_SHA512_C)
mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len ); mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
#endif #endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
} }
...@@ -4873,8 +4914,8 @@ static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, ...@@ -4873,8 +4914,8 @@ static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl, static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len ) const unsigned char *buf, size_t len )
{ {
mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len ); mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len ); mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
} }
#endif #endif
...@@ -4883,7 +4924,7 @@ static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl, ...@@ -4883,7 +4924,7 @@ static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl, static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len ) const unsigned char *buf, size_t len )
{ {
mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len ); mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
} }
#endif #endif
...@@ -4891,7 +4932,7 @@ static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl, ...@@ -4891,7 +4932,7 @@ static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl, static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len ) const unsigned char *buf, size_t len )
{ {
mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len ); mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
} }
#endif #endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
...@@ -4944,29 +4985,29 @@ static void ssl_calc_finished_ssl( ...@@ -4944,29 +4985,29 @@ static void ssl_calc_finished_ssl(
memset( padbuf, 0x36, 48 ); memset( padbuf, 0x36, 48 );
mbedtls_md5_update( &md5, (const unsigned char *) sender, 4 ); mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 );
mbedtls_md5_update( &md5, session->master, 48 ); mbedtls_md5_update_ret( &md5, session->master, 48 );
mbedtls_md5_update( &md5, padbuf, 48 ); mbedtls_md5_update_ret( &md5, padbuf, 48 );
mbedtls_md5_finish( &md5, md5sum ); mbedtls_md5_finish_ret( &md5, md5sum );
mbedtls_sha1_update( &sha1, (const unsigned char *) sender, 4 ); mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 );
mbedtls_sha1_update( &sha1, session->master, 48 ); mbedtls_sha1_update_ret( &sha1, session->master, 48 );
mbedtls_sha1_update( &sha1, padbuf, 40 ); mbedtls_sha1_update_ret( &sha1, padbuf, 40 );
mbedtls_sha1_finish( &sha1, sha1sum ); mbedtls_sha1_finish_ret( &sha1, sha1sum );
memset( padbuf, 0x5C, 48 ); memset( padbuf, 0x5C, 48 );
mbedtls_md5_starts( &md5 ); mbedtls_md5_starts_ret( &md5 );
mbedtls_md5_update( &md5, session->master, 48 ); mbedtls_md5_update_ret( &md5, session->master, 48 );
mbedtls_md5_update( &md5, padbuf, 48 ); mbedtls_md5_update_ret( &md5, padbuf, 48 );
mbedtls_md5_update( &md5, md5sum, 16 ); mbedtls_md5_update_ret( &md5, md5sum, 16 );
mbedtls_md5_finish( &md5, buf ); mbedtls_md5_finish_ret( &md5, buf );
mbedtls_sha1_starts( &sha1 ); mbedtls_sha1_starts_ret( &sha1 );
mbedtls_sha1_update( &sha1, session->master, 48 ); mbedtls_sha1_update_ret( &sha1, session->master, 48 );
mbedtls_sha1_update( &sha1, padbuf , 40 ); mbedtls_sha1_update_ret( &sha1, padbuf , 40 );
mbedtls_sha1_update( &sha1, sha1sum, 20 ); mbedtls_sha1_update_ret( &sha1, sha1sum, 20 );
mbedtls_sha1_finish( &sha1, buf + 16 ); mbedtls_sha1_finish_ret( &sha1, buf + 16 );
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
...@@ -5023,8 +5064,8 @@ static void ssl_calc_finished_tls( ...@@ -5023,8 +5064,8 @@ static void ssl_calc_finished_tls(
? "client finished" ? "client finished"
: "server finished"; : "server finished";
mbedtls_md5_finish( &md5, padbuf ); mbedtls_md5_finish_ret( &md5, padbuf );
mbedtls_sha1_finish( &sha1, padbuf + 16 ); mbedtls_sha1_finish_ret( &sha1, padbuf + 16 );
ssl->handshake->tls_prf( session->master, 48, sender, ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 36, buf, len ); padbuf, 36, buf, len );
...@@ -5075,7 +5116,7 @@ static void ssl_calc_finished_tls_sha256( ...@@ -5075,7 +5116,7 @@ static void ssl_calc_finished_tls_sha256(
? "client finished" ? "client finished"
: "server finished"; : "server finished";
mbedtls_sha256_finish( &sha256, padbuf ); mbedtls_sha256_finish_ret( &sha256, padbuf );
ssl->handshake->tls_prf( session->master, 48, sender, ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 32, buf, len ); padbuf, 32, buf, len );
...@@ -5124,7 +5165,7 @@ static void ssl_calc_finished_tls_sha384( ...@@ -5124,7 +5165,7 @@ static void ssl_calc_finished_tls_sha384(
? "client finished" ? "client finished"
: "server finished"; : "server finished";
mbedtls_sha512_finish( &sha512, padbuf ); mbedtls_sha512_finish_ret( &sha512, padbuf );
ssl->handshake->tls_prf( session->master, 48, sender, ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 48, buf, len ); padbuf, 48, buf, len );
...@@ -5438,17 +5479,17 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) ...@@ -5438,17 +5479,17 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
defined(MBEDTLS_SSL_PROTO_TLS1_1) defined(MBEDTLS_SSL_PROTO_TLS1_1)
mbedtls_md5_init( &handshake->fin_md5 ); mbedtls_md5_init( &handshake->fin_md5 );
mbedtls_sha1_init( &handshake->fin_sha1 ); mbedtls_sha1_init( &handshake->fin_sha1 );
mbedtls_md5_starts( &handshake->fin_md5 ); mbedtls_md5_starts_ret( &handshake->fin_md5 );
mbedtls_sha1_starts( &handshake->fin_sha1 ); mbedtls_sha1_starts_ret( &handshake->fin_sha1 );
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C) #if defined(MBEDTLS_SHA256_C)
mbedtls_sha256_init( &handshake->fin_sha256 ); mbedtls_sha256_init( &handshake->fin_sha256 );
mbedtls_sha256_starts( &handshake->fin_sha256, 0 ); mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 );
#endif #endif
#if defined(MBEDTLS_SHA512_C) #if defined(MBEDTLS_SHA512_C)
mbedtls_sha512_init( &handshake->fin_sha512 ); mbedtls_sha512_init( &handshake->fin_sha512 );
mbedtls_sha512_starts( &handshake->fin_sha512, 1 ); mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 );
#endif #endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
...@@ -6050,12 +6091,19 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, ...@@ -6050,12 +6091,19 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
} }
if( conf->psk != NULL || conf->psk_identity != NULL ) if( conf->psk != NULL )
{ {
mbedtls_zeroize( conf->psk, conf->psk_len );
mbedtls_free( conf->psk ); mbedtls_free( conf->psk );
mbedtls_free( conf->psk_identity );
conf->psk = NULL; conf->psk = NULL;
conf->psk_len = 0;
}
if( conf->psk_identity != NULL )
{
mbedtls_free( conf->psk_identity );
conf->psk_identity = NULL; conf->psk_identity = NULL;
conf->psk_identity_len = 0;
} }
if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL || if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ||
...@@ -6087,7 +6135,11 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, ...@@ -6087,7 +6135,11 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( ssl->handshake->psk != NULL ) if( ssl->handshake->psk != NULL )
{
mbedtls_zeroize( ssl->handshake->psk, ssl->handshake->psk_len );
mbedtls_free( ssl->handshake->psk ); mbedtls_free( ssl->handshake->psk );
ssl->handshake->psk_len = 0;
}
if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
...@@ -6109,6 +6161,8 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, ...@@ -6109,6 +6161,8 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G ) int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G )
{ {
int ret; int ret;
...@@ -6123,6 +6177,24 @@ int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, cons ...@@ -6123,6 +6177,24 @@ int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, cons
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_DEPRECATED_REMOVED */
int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
const unsigned char *dhm_P, size_t P_len,
const unsigned char *dhm_G, size_t G_len )
{
int ret;
if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 ||
( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 )
{
mbedtls_mpi_free( &conf->dhm_P );
mbedtls_mpi_free( &conf->dhm_G );
return( ret );
}
return( 0 );
}
int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ) int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx )
{ {
...@@ -6160,7 +6232,7 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, ...@@ -6160,7 +6232,7 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
{ {
conf->sig_hashes = hashes; conf->sig_hashes = hashes;
} }
#endif #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
/* /*
...@@ -6171,36 +6243,53 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, ...@@ -6171,36 +6243,53 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
{ {
conf->curve_list = curve_list; conf->curve_list = curve_list;
} }
#endif #endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname )
{ {
size_t hostname_len; /* Initialize to suppress unnecessary compiler warning */
size_t hostname_len = 0;
if( hostname == NULL ) /* Check if new hostname is valid before
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); * making any change to current one */
if( hostname != NULL )
{
hostname_len = strlen( hostname );
hostname_len = strlen( hostname ); if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
if( hostname_len + 1 == 0 ) /* Now it's clear that we will overwrite the old hostname,
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); * so we can free it safely */
if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN ) if( ssl->hostname != NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); {
mbedtls_zeroize( ssl->hostname, strlen( ssl->hostname ) );
mbedtls_free( ssl->hostname );
}
ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 ); /* Passing NULL as hostname shall clear the old one */
if( ssl->hostname == NULL ) if( hostname == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); {
ssl->hostname = NULL;
}
else
{
ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 );
if( ssl->hostname == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
memcpy( ssl->hostname, hostname, hostname_len ); memcpy( ssl->hostname, hostname, hostname_len );
ssl->hostname[hostname_len] = '\0'; ssl->hostname[hostname_len] = '\0';
}
return( 0 ); return( 0 );
} }
#endif #endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
...@@ -6860,7 +6949,6 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) ...@@ -6860,7 +6949,6 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
} }
} }
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
...@@ -6902,12 +6990,35 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) ...@@ -6902,12 +6990,35 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
} }
#endif /* MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
/* Determine whether renegotiation attempt should be accepted */ /* Determine whether renegotiation attempt should be accepted */
if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
ssl->conf->allow_legacy_renegotiation ==
MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
{
/*
* Accept renegotiation request
*/
if( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || /* DTLS clients need to know renego is server-initiated */
( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && #if defined(MBEDTLS_SSL_PROTO_DTLS)
ssl->conf->allow_legacy_renegotiation == if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
{
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
}
#endif
ret = ssl_start_renegotiation( ssl );
if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
return( ret );
}
}
else
#endif /* MBEDTLS_SSL_RENEGOTIATION */
{ {
/* /*
* Refuse renegotiation * Refuse renegotiation
...@@ -6945,31 +7056,10 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) ...@@ -6945,31 +7056,10 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
} }
else
{
/*
* Accept renegotiation request
*/
/* DTLS clients need to know renego is server-initiated */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
{
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
}
#endif
ret = ssl_start_renegotiation( ssl );
if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
return( ret );
}
}
return( MBEDTLS_ERR_SSL_WANT_READ ); return( MBEDTLS_ERR_SSL_WANT_READ );
} }
#if defined(MBEDTLS_SSL_RENEGOTIATION)
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
{ {
if( ssl->conf->renego_max_records >= 0 ) if( ssl->conf->renego_max_records >= 0 )
...@@ -7055,7 +7145,9 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, ...@@ -7055,7 +7145,9 @@ static int ssl_write_real( mbedtls_ssl_context *ssl,
int ret; int ret;
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
size_t max_len = mbedtls_ssl_get_max_frag_len( ssl ); size_t max_len = mbedtls_ssl_get_max_frag_len( ssl );
#else
size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
if( len > max_len ) if( len > max_len )
{ {
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
...@@ -7070,7 +7162,6 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, ...@@ -7070,7 +7162,6 @@ static int ssl_write_real( mbedtls_ssl_context *ssl,
#endif #endif
len = max_len; len = max_len;
} }
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
if( ssl->out_left != 0 ) if( ssl->out_left != 0 )
{ {
...@@ -7101,7 +7192,7 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, ...@@ -7101,7 +7192,7 @@ static int ssl_write_real( mbedtls_ssl_context *ssl,
* *
* With non-blocking I/O, ssl_write_real() may return WANT_WRITE, * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
* then the caller will call us again with the same arguments, so * then the caller will call us again with the same arguments, so
* remember wether we already did the split or not. * remember whether we already did the split or not.
*/ */
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
static int ssl_write_split( mbedtls_ssl_context *ssl, static int ssl_write_split( mbedtls_ssl_context *ssl,
...@@ -7531,9 +7622,14 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, ...@@ -7531,9 +7622,14 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
if( endpoint == MBEDTLS_SSL_IS_SERVER ) if( endpoint == MBEDTLS_SSL_IS_SERVER )
{ {
if( ( ret = mbedtls_ssl_conf_dh_param( conf, const unsigned char dhm_p[] =
MBEDTLS_DHM_RFC5114_MODP_2048_P, MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
MBEDTLS_DHM_RFC5114_MODP_2048_G ) ) != 0 ) const unsigned char dhm_g[] =
MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf,
dhm_p, sizeof( dhm_p ),
dhm_g, sizeof( dhm_g ) ) ) != 0 )
{ {
return( ret ); return( ret );
} }
...@@ -8033,4 +8129,148 @@ int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) ...@@ -8033,4 +8129,148 @@ int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
} }
#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 )
{
int ret = 0;
mbedtls_md5_context mbedtls_md5;
mbedtls_sha1_context mbedtls_sha1;
mbedtls_md5_init( &mbedtls_md5 );
mbedtls_sha1_init( &mbedtls_sha1 );
/*
* digitally-signed struct {
* opaque md5_hash[16];
* opaque sha_hash[20];
* };
*
* md5_hash
* MD5(ClientHello.random + ServerHello.random
* + ServerParams);
* sha_hash
* SHA(ClientHello.random + ServerHello.random
* + ServerParams);
*/
if( ( ret = mbedtls_md5_starts_ret( &mbedtls_md5 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_starts_ret", ret );
goto exit;
}
if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5,
ssl->handshake->randbytes, 64 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret );
goto exit;
}
if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, data, data_len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret );
goto exit;
}
if( ( ret = mbedtls_md5_finish_ret( &mbedtls_md5, output ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_finish_ret", ret );
goto exit;
}
if( ( ret = mbedtls_sha1_starts_ret( &mbedtls_sha1 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_starts_ret", ret );
goto exit;
}
if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1,
ssl->handshake->randbytes, 64 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret );
goto exit;
}
if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, data,
data_len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret );
goto exit;
}
if( ( ret = mbedtls_sha1_finish_ret( &mbedtls_sha1,
output + 16 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_finish_ret", ret );
goto exit;
}
exit:
mbedtls_md5_free( &mbedtls_md5 );
mbedtls_sha1_free( &mbedtls_sha1 );
if( ret != 0 )
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( ret );
}
#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 )
{
int ret = 0;
mbedtls_md_context_t ctx;
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
mbedtls_md_init( &ctx );
/*
* digitally-signed struct {
* opaque client_random[32];
* opaque server_random[32];
* ServerDHParams params;
* };
*/
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
goto exit;
}
if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret );
goto exit;
}
if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
goto exit;
}
if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
goto exit;
}
if( ( ret = mbedtls_md_finish( &ctx, output ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
goto exit;
}
exit:
mbedtls_md_free( &ctx );
if( ret != 0 )
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( ret );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */
#endif /* MBEDTLS_SSL_TLS_C */ #endif /* MBEDTLS_SSL_TLS_C */
...@@ -244,21 +244,23 @@ volatile int mbedtls_timing_alarmed = 0; ...@@ -244,21 +244,23 @@ volatile int mbedtls_timing_alarmed = 0;
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 )
{ {
unsigned long delta;
LARGE_INTEGER offset, hfreq;
struct _hr_time *t = (struct _hr_time *) val; struct _hr_time *t = (struct _hr_time *) val;
QueryPerformanceCounter( &offset );
QueryPerformanceFrequency( &hfreq );
delta = (unsigned long)( ( 1000 *
( offset.QuadPart - t->start.QuadPart ) ) /
hfreq.QuadPart );
if( reset ) if( reset )
{
QueryPerformanceCounter( &t->start ); QueryPerformanceCounter( &t->start );
return( 0 );
return( delta ); }
else
{
unsigned long delta;
LARGE_INTEGER now, hfreq;
QueryPerformanceCounter( &now );
QueryPerformanceFrequency( &hfreq );
delta = (unsigned long)( ( now.QuadPart - t->start.QuadPart ) * 1000ul
/ hfreq.QuadPart );
return( delta );
}
} }
/* It's OK to use a global because alarm() is supposed to be global anyway */ /* It's OK to use a global because alarm() is supposed to be global anyway */
...@@ -276,6 +278,14 @@ void mbedtls_set_alarm( int seconds ) ...@@ -276,6 +278,14 @@ void mbedtls_set_alarm( int seconds )
{ {
DWORD ThreadId; DWORD ThreadId;
if( seconds == 0 )
{
/* No need to create a thread for this simple case.
* Also, this shorcut is more reliable at least on MinGW32 */
mbedtls_timing_alarmed = 1;
return;
}
mbedtls_timing_alarmed = 0; mbedtls_timing_alarmed = 0;
alarmMs = seconds * 1000; alarmMs = seconds * 1000;
CloseHandle( CreateThread( NULL, 0, TimerProc, NULL, 0, &ThreadId ) ); CloseHandle( CreateThread( NULL, 0, TimerProc, NULL, 0, &ThreadId ) );
...@@ -285,23 +295,22 @@ void mbedtls_set_alarm( int seconds ) ...@@ -285,23 +295,22 @@ void mbedtls_set_alarm( int seconds )
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 )
{ {
unsigned long delta;
struct timeval offset;
struct _hr_time *t = (struct _hr_time *) val; struct _hr_time *t = (struct _hr_time *) val;
gettimeofday( &offset, NULL );
if( reset ) if( reset )
{ {
t->start.tv_sec = offset.tv_sec; gettimeofday( &t->start, NULL );
t->start.tv_usec = offset.tv_usec;
return( 0 ); return( 0 );
} }
else
delta = ( offset.tv_sec - t->start.tv_sec ) * 1000 {
+ ( offset.tv_usec - t->start.tv_usec ) / 1000; unsigned long delta;
struct timeval now;
return( delta ); gettimeofday( &now, NULL );
delta = ( now.tv_sec - t->start.tv_sec ) * 1000ul
+ ( now.tv_usec - t->start.tv_usec ) / 1000;
return( delta );
}
} }
static void sighandler( int signum ) static void sighandler( int signum )
...@@ -315,6 +324,12 @@ void mbedtls_set_alarm( int seconds ) ...@@ -315,6 +324,12 @@ void mbedtls_set_alarm( int seconds )
mbedtls_timing_alarmed = 0; mbedtls_timing_alarmed = 0;
signal( SIGALRM, sighandler ); signal( SIGALRM, sighandler );
alarm( seconds ); alarm( seconds );
if( seconds == 0 )
{
/* alarm(0) cancelled any previous pending alarm, but the
handler won't fire, so raise the flag straight away. */
mbedtls_timing_alarmed = 1;
}
} }
#endif /* _WIN32 && !EFIX64 && !EFI32 */ #endif /* _WIN32 && !EFIX64 && !EFI32 */
...@@ -378,13 +393,21 @@ static void busy_msleep( unsigned long msec ) ...@@ -378,13 +393,21 @@ static void busy_msleep( unsigned long msec )
(void) j; (void) j;
} }
#define FAIL do \ #define FAIL do \
{ \ { \
if( verbose != 0 ) \ if( verbose != 0 ) \
mbedtls_printf( "failed\n" ); \ { \
\ mbedtls_printf( "failed at line %d\n", __LINE__ ); \
return( 1 ); \ mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \
} while( 0 ) cycles, ratio, millisecs, secs, hardfail, \
(unsigned long) a, (unsigned long) b ); \
mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n", \
mbedtls_timing_get_timer( &hires, 0 ), \
mbedtls_timing_get_timer( &ctx.timer, 0 ), \
mbedtls_timing_get_delay( &ctx ) ); \
} \
return( 1 ); \
} while( 0 )
/* /*
* Checkup routine * Checkup routine
...@@ -394,22 +417,22 @@ static void busy_msleep( unsigned long msec ) ...@@ -394,22 +417,22 @@ static void busy_msleep( unsigned long msec )
*/ */
int mbedtls_timing_self_test( int verbose ) int mbedtls_timing_self_test( int verbose )
{ {
unsigned long cycles, ratio; unsigned long cycles = 0, ratio = 0;
unsigned long millisecs, secs; unsigned long millisecs = 0, secs = 0;
int hardfail; int hardfail = 0;
struct mbedtls_timing_hr_time hires; struct mbedtls_timing_hr_time hires;
uint32_t a, b; uint32_t a = 0, b = 0;
mbedtls_timing_delay_context ctx; mbedtls_timing_delay_context ctx;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " TIMING tests note: will take some time!\n" ); mbedtls_printf( " TIMING tests note: will take some time!\n" );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " ); mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " );
for( secs = 1; secs <= 3; secs++ )
{ {
secs = 1;
(void) mbedtls_timing_get_timer( &hires, 1 ); (void) mbedtls_timing_get_timer( &hires, 1 );
mbedtls_set_alarm( (int) secs ); mbedtls_set_alarm( (int) secs );
...@@ -421,12 +444,7 @@ int mbedtls_timing_self_test( int verbose ) ...@@ -421,12 +444,7 @@ int mbedtls_timing_self_test( int verbose )
/* For some reason on Windows it looks like alarm has an extra delay /* For some reason on Windows it looks like alarm has an extra delay
* (maybe related to creating a new thread). Allow some room here. */ * (maybe related to creating a new thread). Allow some room here. */
if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 ) if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
{ FAIL;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
if( verbose != 0 ) if( verbose != 0 )
...@@ -435,28 +453,22 @@ int mbedtls_timing_self_test( int verbose ) ...@@ -435,28 +453,22 @@ int mbedtls_timing_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " TIMING test #2 (set/get_delay ): " ); mbedtls_printf( " TIMING test #2 (set/get_delay ): " );
for( a = 200; a <= 400; a += 200 )
{ {
for( b = 200; b <= 400; b += 200 ) a = 800;
{ b = 400;
mbedtls_timing_set_delay( &ctx, a, a + b ); mbedtls_timing_set_delay( &ctx, a, a + b ); /* T = 0 */
busy_msleep( a - a / 8 );
if( mbedtls_timing_get_delay( &ctx ) != 0 )
FAIL;
busy_msleep( a / 4 ); busy_msleep( a - a / 4 ); /* T = a - a/4 */
if( mbedtls_timing_get_delay( &ctx ) != 1 ) if( mbedtls_timing_get_delay( &ctx ) != 0 )
FAIL; FAIL;
busy_msleep( b - a / 8 - b / 8 ); busy_msleep( a / 4 + b / 4 ); /* T = a + b/4 */
if( mbedtls_timing_get_delay( &ctx ) != 1 ) if( mbedtls_timing_get_delay( &ctx ) != 1 )
FAIL; FAIL;
busy_msleep( b / 4 ); busy_msleep( b ); /* T = a + b + b/4 */
if( mbedtls_timing_get_delay( &ctx ) != 2 ) if( mbedtls_timing_get_delay( &ctx ) != 2 )
FAIL; FAIL;
}
} }
mbedtls_timing_set_delay( &ctx, 0, 0 ); mbedtls_timing_set_delay( &ctx, 0, 0 );
...@@ -475,7 +487,6 @@ int mbedtls_timing_self_test( int verbose ) ...@@ -475,7 +487,6 @@ int mbedtls_timing_self_test( int verbose )
* On a 4Ghz 32-bit machine the cycle counter wraps about once per second; * On a 4Ghz 32-bit machine the cycle counter wraps about once per second;
* since the whole test is about 10ms, it shouldn't happen twice in a row. * since the whole test is about 10ms, it shouldn't happen twice in a row.
*/ */
hardfail = 0;
hard_test: hard_test:
if( hardfail > 1 ) if( hardfail > 1 )
......
...@@ -96,12 +96,24 @@ static const char *features[] = { ...@@ -96,12 +96,24 @@ static const char *features[] = {
#if defined(MBEDTLS_CAMELLIA_ALT) #if defined(MBEDTLS_CAMELLIA_ALT)
"MBEDTLS_CAMELLIA_ALT", "MBEDTLS_CAMELLIA_ALT",
#endif /* MBEDTLS_CAMELLIA_ALT */ #endif /* MBEDTLS_CAMELLIA_ALT */
#if defined(MBEDTLS_CCM_ALT)
"MBEDTLS_CCM_ALT",
#endif /* MBEDTLS_CCM_ALT */
#if defined(MBEDTLS_CMAC_ALT)
"MBEDTLS_CMAC_ALT",
#endif /* MBEDTLS_CMAC_ALT */
#if defined(MBEDTLS_DES_ALT) #if defined(MBEDTLS_DES_ALT)
"MBEDTLS_DES_ALT", "MBEDTLS_DES_ALT",
#endif /* MBEDTLS_DES_ALT */ #endif /* MBEDTLS_DES_ALT */
#if defined(MBEDTLS_XTEA_ALT) #if defined(MBEDTLS_DHM_ALT)
"MBEDTLS_XTEA_ALT", "MBEDTLS_DHM_ALT",
#endif /* MBEDTLS_XTEA_ALT */ #endif /* MBEDTLS_DHM_ALT */
#if defined(MBEDTLS_ECJPAKE_ALT)
"MBEDTLS_ECJPAKE_ALT",
#endif /* MBEDTLS_ECJPAKE_ALT */
#if defined(MBEDTLS_GCM_ALT)
"MBEDTLS_GCM_ALT",
#endif /* MBEDTLS_GCM_ALT */
#if defined(MBEDTLS_MD2_ALT) #if defined(MBEDTLS_MD2_ALT)
"MBEDTLS_MD2_ALT", "MBEDTLS_MD2_ALT",
#endif /* MBEDTLS_MD2_ALT */ #endif /* MBEDTLS_MD2_ALT */
...@@ -114,6 +126,9 @@ static const char *features[] = { ...@@ -114,6 +126,9 @@ static const char *features[] = {
#if defined(MBEDTLS_RIPEMD160_ALT) #if defined(MBEDTLS_RIPEMD160_ALT)
"MBEDTLS_RIPEMD160_ALT", "MBEDTLS_RIPEMD160_ALT",
#endif /* MBEDTLS_RIPEMD160_ALT */ #endif /* MBEDTLS_RIPEMD160_ALT */
#if defined(MBEDTLS_RSA_ALT)
"MBEDTLS_RSA_ALT",
#endif /* MBEDTLS_RSA_ALT */
#if defined(MBEDTLS_SHA1_ALT) #if defined(MBEDTLS_SHA1_ALT)
"MBEDTLS_SHA1_ALT", "MBEDTLS_SHA1_ALT",
#endif /* MBEDTLS_SHA1_ALT */ #endif /* MBEDTLS_SHA1_ALT */
...@@ -123,6 +138,9 @@ static const char *features[] = { ...@@ -123,6 +138,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SHA512_ALT) #if defined(MBEDTLS_SHA512_ALT)
"MBEDTLS_SHA512_ALT", "MBEDTLS_SHA512_ALT",
#endif /* MBEDTLS_SHA512_ALT */ #endif /* MBEDTLS_SHA512_ALT */
#if defined(MBEDTLS_XTEA_ALT)
"MBEDTLS_XTEA_ALT",
#endif /* MBEDTLS_XTEA_ALT */
#if defined(MBEDTLS_ECP_ALT) #if defined(MBEDTLS_ECP_ALT)
"MBEDTLS_ECP_ALT", "MBEDTLS_ECP_ALT",
#endif /* MBEDTLS_ECP_ALT */ #endif /* MBEDTLS_ECP_ALT */
...@@ -168,6 +186,21 @@ static const char *features[] = { ...@@ -168,6 +186,21 @@ static const char *features[] = {
#if defined(MBEDTLS_AES_DECRYPT_ALT) #if defined(MBEDTLS_AES_DECRYPT_ALT)
"MBEDTLS_AES_DECRYPT_ALT", "MBEDTLS_AES_DECRYPT_ALT",
#endif /* MBEDTLS_AES_DECRYPT_ALT */ #endif /* MBEDTLS_AES_DECRYPT_ALT */
#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
"MBEDTLS_ECDH_GEN_PUBLIC_ALT",
#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
"MBEDTLS_ECDH_COMPUTE_SHARED_ALT",
#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
"MBEDTLS_ECDSA_VERIFY_ALT",
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
#if defined(MBEDTLS_ECDSA_SIGN_ALT)
"MBEDTLS_ECDSA_SIGN_ALT",
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
#if defined(MBEDTLS_ECDSA_GENKEY_ALT)
"MBEDTLS_ECDSA_GENKEY_ALT",
#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
#if defined(MBEDTLS_ECP_INTERNAL_ALT) #if defined(MBEDTLS_ECP_INTERNAL_ALT)
"MBEDTLS_ECP_INTERNAL_ALT", "MBEDTLS_ECP_INTERNAL_ALT",
#endif /* MBEDTLS_ECP_INTERNAL_ALT */ #endif /* MBEDTLS_ECP_INTERNAL_ALT */
......
...@@ -496,9 +496,10 @@ static int x509_parse_int( unsigned char **p, size_t n, int *res ) ...@@ -496,9 +496,10 @@ static int x509_parse_int( unsigned char **p, size_t n, int *res )
return( 0 ); return( 0 );
} }
static int x509_date_is_valid(const mbedtls_x509_time *t) static int x509_date_is_valid(const mbedtls_x509_time *t )
{ {
int ret = MBEDTLS_ERR_X509_INVALID_DATE; int ret = MBEDTLS_ERR_X509_INVALID_DATE;
int month_len;
CHECK_RANGE( 0, 9999, t->year ); CHECK_RANGE( 0, 9999, t->year );
CHECK_RANGE( 0, 23, t->hour ); CHECK_RANGE( 0, 23, t->hour );
...@@ -508,17 +509,22 @@ static int x509_date_is_valid(const mbedtls_x509_time *t) ...@@ -508,17 +509,22 @@ static int x509_date_is_valid(const mbedtls_x509_time *t)
switch( t->mon ) switch( t->mon )
{ {
case 1: case 3: case 5: case 7: case 8: case 10: case 12: case 1: case 3: case 5: case 7: case 8: case 10: case 12:
CHECK_RANGE( 1, 31, t->day ); month_len = 31;
break; break;
case 4: case 6: case 9: case 11: case 4: case 6: case 9: case 11:
CHECK_RANGE( 1, 30, t->day ); month_len = 30;
break; break;
case 2: case 2:
CHECK_RANGE( 1, 28 + (t->year % 4 == 0), t->day ); if( ( !( t->year % 4 ) && t->year % 100 ) ||
!( t->year % 400 ) )
month_len = 29;
else
month_len = 28;
break; break;
default: default:
return( ret ); return( ret );
} }
CHECK_RANGE( 1, month_len, t->day );
return( 0 ); return( 0 );
} }
......
...@@ -51,7 +51,7 @@ static void mbedtls_zeroize( void *v, size_t n ) { ...@@ -51,7 +51,7 @@ static void mbedtls_zeroize( void *v, size_t n ) {
void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
{ {
memset( ctx, 0, sizeof(mbedtls_x509write_cert) ); memset( ctx, 0, sizeof( mbedtls_x509write_cert ) );
mbedtls_mpi_init( &ctx->serial ); mbedtls_mpi_init( &ctx->serial );
ctx->version = MBEDTLS_X509_CRT_VERSION_3; ctx->version = MBEDTLS_X509_CRT_VERSION_3;
...@@ -65,7 +65,7 @@ void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) ...@@ -65,7 +65,7 @@ void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx )
mbedtls_asn1_free_named_data_list( &ctx->issuer ); mbedtls_asn1_free_named_data_list( &ctx->issuer );
mbedtls_asn1_free_named_data_list( &ctx->extensions ); mbedtls_asn1_free_named_data_list( &ctx->extensions );
mbedtls_zeroize( ctx, sizeof(mbedtls_x509write_cert) ); mbedtls_zeroize( ctx, sizeof( mbedtls_x509write_cert ) );
} }
void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version ) void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version )
...@@ -177,8 +177,11 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct ...@@ -177,8 +177,11 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct
memset( buf, 0, sizeof(buf) ); memset( buf, 0, sizeof(buf) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
c = buf + sizeof(buf) - 20; buf + sizeof( buf ) - 20 );
if( ret != 0 )
return( ret );
c = buf + sizeof( buf ) - 20;
len = 20; len = 20;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
...@@ -193,14 +196,17 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert * ...@@ -193,14 +196,17 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *
{ {
int ret; int ret;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
unsigned char *c = buf + sizeof(buf); unsigned char *c = buf + sizeof( buf );
size_t len = 0; size_t len = 0;
memset( buf, 0, sizeof(buf) ); memset( buf, 0, sizeof(buf) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
c = buf + sizeof(buf) - 20; buf + sizeof( buf ) - 20 );
if( ret != 0 )
return( ret );
c = buf + sizeof( buf ) - 20;
len = 20; len = 20;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
...@@ -212,7 +218,7 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert * ...@@ -212,7 +218,7 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *
return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ),
0, buf + sizeof(buf) - len, len ); 0, buf + sizeof( buf ) - len, len );
} }
#endif /* MBEDTLS_SHA1_C */ #endif /* MBEDTLS_SHA1_C */
...@@ -313,12 +319,18 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, ...@@ -313,12 +319,18 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
c = tmp_buf + sizeof( tmp_buf ); c = tmp_buf + sizeof( tmp_buf );
/* Signature algorithm needed in TBS, and later for actual signature */ /* Signature algorithm needed in TBS, and later for actual signature */
pk_alg = mbedtls_pk_get_type( ctx->issuer_key );
if( pk_alg == MBEDTLS_PK_ECKEY ) /* There's no direct way of extracting a signature algorithm
* (represented as an element of mbedtls_pk_type_t) from a PK instance. */
if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_RSA ) )
pk_alg = MBEDTLS_PK_RSA;
else if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_ECDSA ) )
pk_alg = MBEDTLS_PK_ECDSA; pk_alg = MBEDTLS_PK_ECDSA;
else
return( MBEDTLS_ERR_X509_INVALID_ALG );
if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
&sig_oid, &sig_oid_len ) ) != 0 ) &sig_oid, &sig_oid_len ) ) != 0 )
{ {
return( ret ); return( ret );
} }
...@@ -326,13 +338,18 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, ...@@ -326,13 +338,18 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
/* /*
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
*/ */
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); /* Only for v3 */
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 )
MBEDTLS_ASN1_SEQUENCE ) ); {
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED | 3 ) );
}
/* /*
* SubjectPublicKeyInfo * SubjectPublicKeyInfo
...@@ -384,21 +401,30 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, ...@@ -384,21 +401,30 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
/* /*
* Version ::= INTEGER { v1(0), v2(1), v3(2) } * Version ::= INTEGER { v1(0), v2(1), v3(2) }
*/ */
sub_len = 0;
MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) ); /* Can be omitted for v1 */
len += sub_len; if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 )
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); {
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | sub_len = 0;
MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) );
len += sub_len;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
}
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE ) ); MBEDTLS_ASN1_SEQUENCE ) );
/* /*
* Make signature * Make signature
*/ */
mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c,
len, hash ) ) != 0 )
{
return( ret );
}
if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len, if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
f_rng, p_rng ) ) != 0 ) f_rng, p_rng ) ) != 0 )
......
...@@ -50,7 +50,7 @@ static void mbedtls_zeroize( void *v, size_t n ) { ...@@ -50,7 +50,7 @@ static void mbedtls_zeroize( void *v, size_t n ) {
void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
{ {
memset( ctx, 0, sizeof(mbedtls_x509write_csr) ); memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
} }
void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
...@@ -58,7 +58,7 @@ void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) ...@@ -58,7 +58,7 @@ void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
mbedtls_asn1_free_named_data_list( &ctx->subject ); mbedtls_asn1_free_named_data_list( &ctx->subject );
mbedtls_asn1_free_named_data_list( &ctx->extensions ); mbedtls_asn1_free_named_data_list( &ctx->extensions );
mbedtls_zeroize( ctx, sizeof(mbedtls_x509write_csr) ); mbedtls_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
} }
void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ) void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
...@@ -194,14 +194,21 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s ...@@ -194,14 +194,21 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s
*/ */
mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
pk_alg = mbedtls_pk_get_type( ctx->key ); if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
if( pk_alg == MBEDTLS_PK_ECKEY ) f_rng, p_rng ) ) != 0 )
{
return( ret );
}
if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) )
pk_alg = MBEDTLS_PK_RSA;
else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) )
pk_alg = MBEDTLS_PK_ECDSA; pk_alg = MBEDTLS_PK_ECDSA;
else
return( MBEDTLS_ERR_X509_INVALID_ALG );
if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
f_rng, p_rng ) ) != 0 || &sig_oid, &sig_oid_len ) ) != 0 )
( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
&sig_oid, &sig_oid_len ) ) != 0 )
{ {
return( ret ); return( ret );
} }
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "mbedtls/debug.h"
#include "user_mbedtls.h"
#ifdef HAVE_SSL_SERVER_CRT #ifdef HAVE_SSL_SERVER_CRT
#include HAVE_SSL_SERVER_CRT #include HAVE_SSL_SERVER_CRT
#else #else
...@@ -611,6 +614,13 @@ static int tls_cert_verify(lua_State *L) ...@@ -611,6 +614,13 @@ static int tls_cert_verify(lua_State *L)
return 1; return 1;
} }
#if defined(MBEDTLS_DEBUG_C)
static int tls_set_debug_threshold(lua_State *L) {
mbedtls_debug_set_threshold(luaL_checkint( L, 1 ));
return 0;
}
#endif
static const LUA_REG_TYPE tls_socket_map[] = { static const LUA_REG_TYPE tls_socket_map[] = {
{ LSTRKEY( "connect" ), LFUNCVAL( tls_socket_connect ) }, { LSTRKEY( "connect" ), LFUNCVAL( tls_socket_connect ) },
{ LSTRKEY( "close" ), LFUNCVAL( tls_socket_close ) }, { LSTRKEY( "close" ), LFUNCVAL( tls_socket_close ) },
...@@ -634,6 +644,9 @@ const LUA_REG_TYPE tls_cert_map[] = { ...@@ -634,6 +644,9 @@ const LUA_REG_TYPE tls_cert_map[] = {
static const LUA_REG_TYPE tls_map[] = { static const LUA_REG_TYPE tls_map[] = {
{ LSTRKEY( "createConnection" ), LFUNCVAL( tls_socket_create ) }, { LSTRKEY( "createConnection" ), LFUNCVAL( tls_socket_create ) },
#if defined(MBEDTLS_DEBUG_C)
{ LSTRKEY( "setDebug" ), LFUNCVAL( tls_set_debug_threshold ) },
#endif
{ LSTRKEY( "cert" ), LROVAL( tls_cert_map ) }, { LSTRKEY( "cert" ), LROVAL( tls_cert_map ) },
{ LSTRKEY( "__metatable" ), LROVAL( tls_map ) }, { LSTRKEY( "__metatable" ), LROVAL( tls_map ) },
{ LNILKEY, LNILVAL } { LNILKEY, LNILVAL }
......
...@@ -291,3 +291,10 @@ firmware image. ...@@ -291,3 +291,10 @@ firmware image.
The alternative approach is easier for development, and that is to supply the PEM data as a string value to `tls.cert.verify`. This The alternative approach is easier for development, and that is to supply the PEM data as a string value to `tls.cert.verify`. This
will store the certificate into the flash chip and turn on verification for that certificate. Subsequent boots of the nodemcu can then will store the certificate into the flash chip and turn on verification for that certificate. Subsequent boots of the nodemcu can then
use `tls.cert.verify(true)` and use the stored certificate. use `tls.cert.verify(true)` and use the stored certificate.
# tls.setDebug function
mbedTLS can be compiled with debug support. If so, the tls.setDebug
function is mapped to the `mbedtls_debug_set_threshold` function and
can be used to enable or disable debugging spew to the console.
See mbedTLS's documentation for more details.
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