[MBEDTLS] Update to version 2.7.6. CORE-15280

Note: this disables the MBEDTLS_DEPRECATED_REMOVED configuration value,
because we require the now-deprecated MD5 & SHA functions for bcrypt.
This commit is contained in:
Thomas Faber 2018-10-31 16:00:34 +01:00
parent 9f1e053260
commit d9e6c9b539
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
124 changed files with 10330 additions and 3757 deletions

View file

@ -54,6 +54,7 @@ list(APPEND SOURCE
platform.c platform.c
ripemd160.c ripemd160.c
rsa.c rsa.c
rsa_internal.c
sha1.c sha1.c
sha256.c sha256.c
sha512.c sha512.c

View file

@ -767,12 +767,14 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
} }
#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ #endif /* !MBEDTLS_AES_ENCRYPT_ALT */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16], const unsigned char input[16],
unsigned char output[16] ) unsigned char output[16] )
{ {
mbedtls_internal_aes_encrypt( ctx, input, output ); mbedtls_internal_aes_encrypt( ctx, input, output );
} }
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/* /*
* AES-ECB block decryption * AES-ECB block decryption
@ -833,12 +835,14 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
} }
#endif /* !MBEDTLS_AES_DECRYPT_ALT */ #endif /* !MBEDTLS_AES_DECRYPT_ALT */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16], const unsigned char input[16],
unsigned char output[16] ) unsigned char output[16] )
{ {
mbedtls_internal_aes_decrypt( ctx, input, output ); mbedtls_internal_aes_decrypt( ctx, input, output );
} }
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/* /*
* AES-ECB block encryption/decryption * AES-ECB block encryption/decryption
@ -1237,9 +1241,11 @@ static const int aes_test_ctr_len[3] =
*/ */
int mbedtls_aes_self_test( int verbose ) int mbedtls_aes_self_test( int verbose )
{ {
int ret = 0, i, j, u, v; int ret = 0, i, j, u, mode;
unsigned int keybits;
unsigned char key[32]; unsigned char key[32];
unsigned char buf[64]; unsigned char buf[64];
const unsigned char *aes_tests;
#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) #if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
unsigned char iv[16]; unsigned char iv[16];
#endif #endif
@ -1265,45 +1271,52 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( buf, 0, 16 ); memset( buf, 0, 16 );
if( v == MBEDTLS_AES_DECRYPT ) if( mode == MBEDTLS_AES_DECRYPT )
{ {
mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
aes_tests = aes_test_ecb_dec[u];
for( j = 0; j < 10000; j++ )
mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
} }
else else
{ {
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
aes_tests = aes_test_ecb_enc[u];
}
for( j = 0; j < 10000; j++ ) /*
mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); * AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) * MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{
mbedtls_printf( "skipped\n" );
continue;
}
else if( ret != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit; goto exit;
} }
for( j = 0; j < 10000; j++ )
{
ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
if( ret != 0 )
goto exit;
}
if( memcmp( buf, aes_tests, 16 ) != 0 )
{
ret = 1;
goto exit;
} }
if( verbose != 0 ) if( verbose != 0 )
@ -1320,56 +1333,65 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( iv , 0, 16 ); memset( iv , 0, 16 );
memset( prv, 0, 16 ); memset( prv, 0, 16 );
memset( buf, 0, 16 ); memset( buf, 0, 16 );
if( v == MBEDTLS_AES_DECRYPT ) if( mode == MBEDTLS_AES_DECRYPT )
{ {
mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
aes_tests = aes_test_cbc_dec[u];
for( j = 0; j < 10000; j++ )
mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
} }
else else
{ {
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
aes_tests = aes_test_cbc_enc[u];
}
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{
mbedtls_printf( "skipped\n" );
continue;
}
else if( ret != 0 )
{
goto exit;
}
for( j = 0; j < 10000; j++ ) for( j = 0; j < 10000; j++ )
{
if( mode == MBEDTLS_AES_ENCRYPT )
{ {
unsigned char tmp[16]; unsigned char tmp[16];
mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
memcpy( tmp, prv, 16 ); memcpy( tmp, prv, 16 );
memcpy( prv, buf, 16 ); memcpy( prv, buf, 16 );
memcpy( buf, tmp, 16 ); memcpy( buf, tmp, 16 );
} }
if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
{ if( ret != 0 )
if( verbose != 0 ) goto exit;
mbedtls_printf( "failed\n" );
}
if( memcmp( buf, aes_tests, 16 ) != 0 )
{
ret = 1; ret = 1;
goto exit; goto exit;
} }
}
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
@ -1386,46 +1408,53 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, aes_test_cfb128_iv, 16 ); memcpy( iv, aes_test_cfb128_iv, 16 );
memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
offset = 0; offset = 0;
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
/*
if( v == MBEDTLS_AES_DECRYPT ) * AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{ {
memcpy( buf, aes_test_cfb128_ct[u], 64 ); mbedtls_printf( "skipped\n" );
mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); continue;
}
if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) else if( ret != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit; goto exit;
} }
if( mode == MBEDTLS_AES_DECRYPT )
{
memcpy( buf, aes_test_cfb128_ct[u], 64 );
aes_tests = aes_test_cfb128_pt;
} }
else else
{ {
memcpy( buf, aes_test_cfb128_pt, 64 ); memcpy( buf, aes_test_cfb128_pt, 64 );
mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); aes_tests = aes_test_cfb128_ct[u];
}
if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
if( ret != 0 )
goto exit;
if( memcmp( buf, aes_tests, 64 ) != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1; ret = 1;
goto exit; goto exit;
} }
}
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
@ -1442,52 +1471,42 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CTR-128 (%s): ", mbedtls_printf( " AES-CTR-128 (%s): ",
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
memcpy( key, aes_test_ctr_key[u], 16 ); memcpy( key, aes_test_ctr_key[u], 16 );
offset = 0; offset = 0;
mbedtls_aes_setkey_enc( &ctx, key, 128 ); if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
if( v == MBEDTLS_AES_DECRYPT )
{
len = aes_test_ctr_len[u];
memcpy( buf, aes_test_ctr_ct[u], len );
mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
buf, buf );
if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit; goto exit;
}
len = aes_test_ctr_len[u];
if( mode == MBEDTLS_AES_DECRYPT )
{
memcpy( buf, aes_test_ctr_ct[u], len );
aes_tests = aes_test_ctr_pt[u];
} }
else else
{ {
len = aes_test_ctr_len[u];
memcpy( buf, aes_test_ctr_pt[u], len ); memcpy( buf, aes_test_ctr_pt[u], len );
aes_tests = aes_test_ctr_ct[u];
}
mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
buf, buf ); stream_block, buf, buf );
if( ret != 0 )
goto exit;
if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) if( memcmp( buf, aes_tests, len ) != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1; ret = 1;
goto exit; goto exit;
} }
}
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
@ -1500,6 +1519,9 @@ int mbedtls_aes_self_test( int verbose )
ret = 0; ret = 0;
exit: exit:
if( ret != 0 && verbose != 0 )
mbedtls_printf( "failed\n" );
mbedtls_aes_free( &ctx ); mbedtls_aes_free( &ctx );
return( ret ); return( ret );

View file

@ -85,7 +85,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
return( 4 ); return( 4 );
} }
#if SIZE_MAX > 0xFFFFFFFF
if( len <= 0xFFFFFFFF ) if( len <= 0xFFFFFFFF )
#endif
{ {
if( *p - start < 5 ) if( *p - start < 5 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@ -98,7 +100,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
return( 5 ); return( 5 );
} }
#if SIZE_MAX > 0xFFFFFFFF
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
#endif
} }
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
@ -234,7 +238,6 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
int ret; int ret;
size_t len = 0; size_t len = 0;
// TODO negative values and values larger than 128
// DER format assumes 2s complement for numbers, so the leftmost bit // DER format assumes 2s complement for numbers, so the leftmost bit
// should be 0 for positive numbers and 1 for negative numbers. // should be 0 for positive numbers and 1 for negative numbers.
// //

View file

@ -65,6 +65,11 @@ static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) {
volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0; volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0;
} }
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
#define biL (ciL << 3) /* bits in limb */ #define biL (ciL << 3) /* bits in limb */
#define biH (ciL << 2) /* half limb size */ #define biH (ciL << 2) /* half limb size */
@ -674,16 +679,20 @@ cleanup:
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ) int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
{ {
int ret; int ret;
size_t i, j, n; size_t i, j;
size_t const limbs = CHARS_TO_LIMBS( buflen );
for( n = 0; n < buflen; n++ ) /* Ensure that target MPI has exactly the necessary number of limbs */
if( buf[n] != 0 ) if( X->n != limbs )
break; {
mbedtls_mpi_free( X );
mbedtls_mpi_init( X );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
}
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
for( i = buflen, j = 0; i > n; i--, j++ ) for( i = buflen, j = 0; i > 0; i--, j++ )
X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3); X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
cleanup: cleanup:
@ -1616,7 +1625,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
int neg; int neg;
if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
@ -1884,6 +1893,7 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
cleanup: cleanup:
mbedtls_zeroize( buf, sizeof( buf ) );
return( ret ); return( ret );
} }

View file

@ -51,6 +51,8 @@
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#if !defined(MBEDTLS_CCM_ALT)
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
@ -350,6 +352,7 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
return( 0 ); return( 0 );
} }
#endif /* !MBEDTLS_CCM_ALT */
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/* /*
@ -357,7 +360,8 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
*/ */
#define NB_TESTS 3 #define NB_TESTS 3
#define CCM_SELFTEST_PT_MAX_LEN 24
#define CCM_SELFTEST_CT_MAX_LEN 32
/* /*
* The data is the same for all tests, only the used length changes * The data is the same for all tests, only the used length changes
*/ */
@ -377,7 +381,7 @@ static const unsigned char ad[] = {
0x10, 0x11, 0x12, 0x13 0x10, 0x11, 0x12, 0x13
}; };
static const unsigned char msg[] = { static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
@ -388,7 +392,7 @@ static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
static const unsigned char res[NB_TESTS][32] = { static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
@ -402,7 +406,13 @@ static const unsigned char res[NB_TESTS][32] = {
int mbedtls_ccm_self_test( int verbose ) int mbedtls_ccm_self_test( int verbose )
{ {
mbedtls_ccm_context ctx; mbedtls_ccm_context ctx;
unsigned char out[32]; /*
* Some hardware accelerators require the input and output buffers
* would be in RAM, because the flash is not accessible.
* Use buffers on the stack to hold the test vectors data.
*/
unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
size_t i; size_t i;
int ret; int ret;
@ -421,27 +431,32 @@ int mbedtls_ccm_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 );
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
memcpy( plaintext, msg, msg_len[i] );
ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i], ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
iv, iv_len[i], ad, add_len[i], iv, iv_len[i], ad, add_len[i],
msg, out, plaintext, ciphertext,
out + msg_len[i], tag_len[i] ); ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 || if( ret != 0 ||
memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 ) memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 )
{ {
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
return( 1 ); return( 1 );
} }
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
iv, iv_len[i], ad, add_len[i], iv, iv_len[i], ad, add_len[i],
res[i], out, ciphertext, plaintext,
res[i] + msg_len[i], tag_len[i] ); ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 || if( ret != 0 ||
memcmp( out, msg, msg_len[i] ) != 0 ) memcmp( plaintext, msg, msg_len[i] ) != 0 )
{ {
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );

View file

@ -58,10 +58,6 @@
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
@ -327,8 +323,10 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
/* /*
* If there is not enough data for a full block, cache it. * If there is not enough data for a full block, cache it.
*/ */
if( ( ctx->operation == MBEDTLS_DECRYPT && if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
ilen <= block_size - ctx->unprocessed_len ) || ilen <= block_size - ctx->unprocessed_len ) ||
( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
ilen < block_size - ctx->unprocessed_len ) ||
( ctx->operation == MBEDTLS_ENCRYPT && ( ctx->operation == MBEDTLS_ENCRYPT &&
ilen < block_size - ctx->unprocessed_len ) ) ilen < block_size - ctx->unprocessed_len ) )
{ {
@ -374,9 +372,17 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
} }
/* Encryption: only cache partial blocks
* Decryption w/ padding: always keep at least one whole block
* Decryption w/o padding: only cache partial blocks
*/
copy_len = ilen % block_size; copy_len = ilen % block_size;
if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) if( copy_len == 0 &&
ctx->operation == MBEDTLS_DECRYPT &&
NULL != ctx->add_padding)
{
copy_len = block_size; copy_len = block_size;
}
memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
copy_len ); copy_len );
@ -518,14 +524,14 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
if( NULL == input || NULL == data_len ) if( NULL == input || NULL == data_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
bad = 0xFF; bad = 0x80;
*data_len = 0; *data_len = 0;
for( i = input_len; i > 0; i-- ) for( i = input_len; i > 0; i-- )
{ {
prev_done = done; prev_done = done;
done |= ( input[i-1] != 0 ); done |= ( input[i - 1] != 0 );
*data_len |= ( i - 1 ) * ( done != prev_done ); *data_len |= ( i - 1 ) * ( done != prev_done );
bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); bad ^= input[i - 1] * ( done != prev_done );
} }
return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );

View file

@ -67,6 +67,8 @@
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
@ -166,7 +168,9 @@ exit:
return( ret ); return( ret );
} }
#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
#if !defined(MBEDTLS_CMAC_ALT)
static void cmac_xor_block( unsigned char *output, const unsigned char *input1, static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
const unsigned char *input2, const unsigned char *input2,
const size_t block_size ) const size_t block_size )
@ -470,6 +474,8 @@ exit:
} }
#endif /* MBEDTLS_AES_C */ #endif /* MBEDTLS_AES_C */
#endif /* !MBEDTLS_CMAC_ALT */
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* CMAC test data for SP800-38B * CMAC test data for SP800-38B
@ -767,7 +773,7 @@ static int cmac_test_subkeys( int verbose,
int block_size, int block_size,
int num_tests ) int num_tests )
{ {
int i, ret; int i, ret = 0;
mbedtls_cipher_context_t ctx; mbedtls_cipher_context_t ctx;
const mbedtls_cipher_info_t *cipher_info; const mbedtls_cipher_info_t *cipher_info;
unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
@ -828,6 +834,7 @@ static int cmac_test_subkeys( int verbose,
mbedtls_cipher_free( &ctx ); mbedtls_cipher_free( &ctx );
} }
ret = 0;
goto exit; goto exit;
cleanup: cleanup:
@ -849,7 +856,7 @@ static int cmac_test_wth_cipher( int verbose,
int num_tests ) int num_tests )
{ {
const mbedtls_cipher_info_t *cipher_info; const mbedtls_cipher_info_t *cipher_info;
int i, ret; int i, ret = 0;
unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX]; unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
cipher_info = mbedtls_cipher_info_from_type( cipher_type ); cipher_info = mbedtls_cipher_info_from_type( cipher_type );
@ -883,6 +890,7 @@ static int cmac_test_wth_cipher( int verbose,
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
} }
ret = 0;
exit: exit:
return( ret ); return( ret );

View file

@ -21,7 +21,7 @@
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*/ */
/* /*
* The NIST SP 800-90 DRBGs are described in the following publucation. * The NIST SP 800-90 DRBGs are described in the following publication.
* *
* http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
*/ */
@ -96,11 +96,15 @@ int mbedtls_ctr_drbg_seed_entropy_len(
/* /*
* Initialize with an empty key * Initialize with an empty key
*/ */
mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ); if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
{
return( ret ); return( ret );
}
return( 0 ); return( 0 );
} }
@ -150,6 +154,7 @@ static int block_cipher_df( unsigned char *output,
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
unsigned char *p, *iv; unsigned char *p, *iv;
mbedtls_aes_context aes_ctx; mbedtls_aes_context aes_ctx;
int ret = 0;
int i, j; int i, j;
size_t buf_len, use_len; size_t buf_len, use_len;
@ -182,7 +187,10 @@ static int block_cipher_df( unsigned char *output,
for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ ) for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
key[i] = i; key[i] = i;
mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ); if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
/* /*
* Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
@ -201,7 +209,10 @@ static int block_cipher_df( unsigned char *output,
use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ); if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
{
goto exit;
}
} }
memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
@ -215,20 +226,40 @@ static int block_cipher_df( unsigned char *output,
/* /*
* Do final encryption with reduced data * Do final encryption with reduced data
*/ */
mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ); if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
p = output; p = output;
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
{ {
mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
{
goto exit;
}
memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
} }
exit:
mbedtls_aes_free( &aes_ctx ); mbedtls_aes_free( &aes_ctx );
/*
* tidy up the stack
*/
mbedtls_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( tmp, sizeof( tmp ) );
mbedtls_zeroize( key, sizeof( key ) );
mbedtls_zeroize( chain, sizeof( chain ) );
if( 0 != ret )
{
/*
* wipe partial seed from memory
*/
mbedtls_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
}
return( 0 ); return( ret );
} }
static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
@ -237,6 +268,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = tmp; unsigned char *p = tmp;
int i, j; int i, j;
int ret = 0;
memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
@ -252,7 +284,10 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
/* /*
* Crypt counter block * Crypt counter block
*/ */
mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ); if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
{
return( ret );
}
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
} }
@ -263,7 +298,10 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
/* /*
* Update key and counter * Update key and counter
*/ */
mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ); if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE ); memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
return( 0 ); return( 0 );
@ -291,6 +329,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
{ {
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0; size_t seedlen = 0;
int ret;
if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
@ -321,12 +360,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
/* /*
* Reduce to 384 bits * Reduce to 384 bits
*/ */
block_cipher_df( seed, seed, seedlen ); if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
{
return( ret );
}
/* /*
* Update state * Update state
*/ */
ctr_drbg_update_internal( ctx, seed ); if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
{
return( ret );
}
ctx->reseed_counter = 1; ctx->reseed_counter = 1;
return( 0 ); return( 0 );
@ -356,15 +401,22 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
ctx->prediction_resistance ) ctx->prediction_resistance )
{ {
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
{
return( ret ); return( ret );
}
add_len = 0; add_len = 0;
} }
if( add_len > 0 ) if( add_len > 0 )
{ {
block_cipher_df( add_input, additional, add_len ); if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
ctr_drbg_update_internal( ctx, add_input ); {
return( ret );
}
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
{
return( ret );
}
} }
while( output_len > 0 ) while( output_len > 0 )
@ -379,7 +431,10 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
/* /*
* Crypt counter block * Crypt counter block
*/ */
mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ); if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
{
return( ret );
}
use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
output_len; output_len;
@ -391,7 +446,10 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
output_len -= use_len; output_len -= use_len;
} }
ctr_drbg_update_internal( ctx, add_input ); if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
{
return( ret );
}
ctx->reseed_counter++; ctx->reseed_counter++;
@ -432,20 +490,20 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
goto exit; goto exit;
if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT ) if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
{
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
goto exit; else
}
ret = 0; ret = 0;
exit: exit:
mbedtls_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( ret ); return( ret );
} }
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
@ -464,15 +522,17 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char
} }
if( fread( buf, 1, n, f ) != n ) if( fread( buf, 1, n, f ) != n )
{ ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
fclose( f ); else
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
}
fclose( f );
mbedtls_ctr_drbg_update( ctx, buf, n ); mbedtls_ctr_drbg_update( ctx, buf, n );
fclose( f );
mbedtls_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
} }
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */

View file

@ -93,7 +93,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
va_start( argp, format ); va_start( argp, format );
#if defined(_WIN32) #if defined(_WIN32)
#if defined(_TRUNCATE) #if defined(_TRUNCATE) && !defined(__MINGW32__)
ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp ); ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
#else #else
ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );

View file

@ -59,6 +59,7 @@
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#if !defined(MBEDTLS_DHM_ALT)
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0; volatile unsigned char *p = v; while( n-- ) *p++ = 0;
@ -95,6 +96,9 @@ static int dhm_read_bignum( mbedtls_mpi *X,
* *
* Parameter should be: 2 <= public_param <= P - 2 * Parameter should be: 2 <= public_param <= P - 2
* *
* This means that we need to return an error if
* public_param < 2 or public_param > P-2
*
* For more information on the attack, see: * For more information on the attack, see:
* http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
* http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
@ -102,17 +106,17 @@ static int dhm_read_bignum( mbedtls_mpi *X,
static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P ) static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
{ {
mbedtls_mpi L, U; mbedtls_mpi L, U;
int ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; int ret = 0;
mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
if( mbedtls_mpi_cmp_mpi( param, &L ) >= 0 && if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
mbedtls_mpi_cmp_mpi( param, &U ) <= 0 ) mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
{ {
ret = 0; ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
} }
cleanup: cleanup:
@ -189,10 +193,15 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
/* /*
* export P, G, GX * export P, G, GX
*/ */
#define DHM_MPI_EXPORT(X,n) \ #define DHM_MPI_EXPORT( X, n ) \
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, p + 2, n ) ); \ do { \
*p++ = (unsigned char)( n >> 8 ); \ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
*p++ = (unsigned char)( n ); p += n; p + 2, \
( n ) ) ); \
*p++ = (unsigned char)( ( n ) >> 8 ); \
*p++ = (unsigned char)( ( n ) ); \
p += ( n ); \
} while( 0 )
n1 = mbedtls_mpi_size( &ctx->P ); n1 = mbedtls_mpi_size( &ctx->P );
n2 = mbedtls_mpi_size( &ctx->G ); n2 = mbedtls_mpi_size( &ctx->G );
@ -215,6 +224,28 @@ cleanup:
return( 0 ); return( 0 );
} }
/*
* Set prime modulus and generator
*/
int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
const mbedtls_mpi *P,
const mbedtls_mpi *G )
{
int ret;
if( ctx == NULL || P == NULL || G == NULL )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
{
return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
}
ctx->len = mbedtls_mpi_size( &ctx->P );
return( 0 );
}
/* /*
* Import the peer's public value G^Y * Import the peer's public value G^Y
*/ */
@ -402,10 +433,11 @@ cleanup:
*/ */
void mbedtls_dhm_free( mbedtls_dhm_context *ctx ) void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
{ {
mbedtls_mpi_free( &ctx->pX); mbedtls_mpi_free( &ctx->Vf ); mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf );
mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY ); mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP );
mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
mbedtls_mpi_free( &ctx->P ); mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X );
mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->P );
mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
} }
@ -544,7 +576,10 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
if( fread( *buf, 1, *n, f ) != *n ) if( fread( *buf, 1, *n, f ) != *n )
{ {
fclose( f ); fclose( f );
mbedtls_zeroize( *buf, *n + 1 );
mbedtls_free( *buf ); mbedtls_free( *buf );
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
} }
@ -579,6 +614,7 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
} }
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */
#endif /* MBEDTLS_ASN1_PARSE_C */ #endif /* MBEDTLS_ASN1_PARSE_C */
#endif /* MBEDTLS_DHM_ALT */
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)

View file

@ -40,6 +40,7 @@
#include <string.h> #include <string.h>
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
/* /*
* Generate public key: simple wrapper around mbedtls_ecp_gen_keypair * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair
*/ */
@ -49,7 +50,9 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp
{ {
return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
} }
#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
/* /*
* Compute shared secret (SEC1 3.3.1) * Compute shared secret (SEC1 3.3.1)
*/ */
@ -83,6 +86,7 @@ cleanup:
return( ret ); return( ret );
} }
#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
/* /*
* Initialize context * Initialize context

View file

@ -67,6 +67,7 @@ cleanup:
return( ret ); return( ret );
} }
#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
/* /*
* Compute ECDSA signature of a hashed message (SEC1 4.1.3) * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
* Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
@ -83,6 +84,10 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
if( grp->N.p == NULL ) if( grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
/* Make sure d is in range 1..n-1 */
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
return( MBEDTLS_ERR_ECP_INVALID_KEY );
mbedtls_ecp_point_init( &R ); mbedtls_ecp_point_init( &R );
mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t ); mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
@ -155,6 +160,7 @@ cleanup:
return( ret ); return( ret );
} }
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/* /*
@ -194,6 +200,7 @@ cleanup:
} }
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
/* /*
* Verify ECDSA signature of hashed message (SEC1 4.1.4) * Verify ECDSA signature of hashed message (SEC1 4.1.4)
* Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
@ -279,6 +286,7 @@ cleanup:
return( ret ); return( ret );
} }
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
/* /*
* Convert a signature (given by context) to ASN.1 * Convert a signature (given by context) to ASN.1
@ -394,6 +402,9 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
&ctx->Q, &r, &s ) ) != 0 ) &ctx->Q, &r, &s ) ) != 0 )
goto cleanup; goto cleanup;
/* At this point we know that the buffer starts with a valid signature.
* Return 0 if the buffer just contains the signature, and a specific
* error code if the valid signature is followed by more data. */
if( p != end ) if( p != end )
ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
@ -404,6 +415,7 @@ cleanup:
return( ret ); return( ret );
} }
#if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
/* /*
* Generate key pair * Generate key pair
*/ */
@ -413,6 +425,7 @@ int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
return( mbedtls_ecp_group_load( &ctx->grp, gid ) || return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ); mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
} }
#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
/* /*
* Set context from an mbedtls_ecp_keypair * Set context from an mbedtls_ecp_keypair

View file

@ -38,6 +38,8 @@
#include <string.h> #include <string.h>
#if !defined(MBEDTLS_ECJPAKE_ALT)
/* /*
* Convert a mbedtls_ecjpake_role to identifier string * Convert a mbedtls_ecjpake_role to identifier string
*/ */
@ -766,6 +768,7 @@ cleanup:
#undef ID_MINE #undef ID_MINE
#undef ID_PEER #undef ID_PEER
#endif /* ! MBEDTLS_ECJPAKE_ALT */
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)

View file

@ -1450,7 +1450,12 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
cleanup: cleanup:
if( T != NULL && ! p_eq_g ) /* There are two cases where T is not stored in grp:
* - P != G
* - An intermediate operation failed before setting grp->T
* In either case, T must be freed.
*/
if( T != NULL && T != grp->T )
{ {
for( i = 0; i < pre_len; i++ ) for( i = 0; i < pre_len; i++ )
mbedtls_ecp_point_free( &T[i] ); mbedtls_ecp_point_free( &T[i] );
@ -1955,7 +1960,6 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
{ {
/* SEC1 3.2.1: Generate d such that 1 <= n < N */ /* SEC1 3.2.1: Generate d such that 1 <= n < N */
int count = 0; int count = 0;
unsigned char rnd[MBEDTLS_ECP_MAX_BYTES];
/* /*
* Match the procedure given in RFC 6979 (deterministic ECDSA): * Match the procedure given in RFC 6979 (deterministic ECDSA):
@ -1966,8 +1970,7 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
*/ */
do do
{ {
MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
/* /*

View file

@ -70,21 +70,26 @@ static void mbedtls_zeroize( void *v, size_t n ) {
void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
{ {
memset( ctx, 0, sizeof(mbedtls_entropy_context) ); ctx->source_count = 0;
memset( ctx->source, 0, sizeof( ctx->source ) );
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex ); mbedtls_mutex_init( &ctx->mutex );
#endif #endif
ctx->accumulator_started = 0;
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_starts( &ctx->accumulator, 0 ); mbedtls_sha512_init( &ctx->accumulator );
#else #else
mbedtls_sha256_starts( &ctx->accumulator, 0 ); mbedtls_sha256_init( &ctx->accumulator );
#endif #endif
#if defined(MBEDTLS_HAVEGE_C) #if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_init( &ctx->havege_data ); mbedtls_havege_init( &ctx->havege_data );
#endif #endif
/* Reminder: Update ENTROPY_HAVE_STRONG in the test files
* when adding more strong entropy sources here. */
#if defined(MBEDTLS_TEST_NULL_ENTROPY) #if defined(MBEDTLS_TEST_NULL_ENTROPY)
mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL, mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
1, MBEDTLS_ENTROPY_SOURCE_STRONG ); 1, MBEDTLS_ENTROPY_SOURCE_STRONG );
@ -115,6 +120,7 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
MBEDTLS_ENTROPY_BLOCK_SIZE, MBEDTLS_ENTROPY_BLOCK_SIZE,
MBEDTLS_ENTROPY_SOURCE_STRONG ); MBEDTLS_ENTROPY_SOURCE_STRONG );
ctx->initial_entropy_run = 0;
#endif #endif
#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
} }
@ -127,7 +133,17 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &ctx->mutex ); mbedtls_mutex_free( &ctx->mutex );
#endif #endif
mbedtls_zeroize( ctx, sizeof( mbedtls_entropy_context ) ); #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_free( &ctx->accumulator );
#else
mbedtls_sha256_free( &ctx->accumulator );
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
ctx->initial_entropy_run = 0;
#endif
ctx->source_count = 0;
mbedtls_zeroize( ctx->source, sizeof( ctx->source ) );
ctx->accumulator_started = 0;
} }
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
@ -174,13 +190,16 @@ static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id
unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE]; unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
size_t use_len = len; size_t use_len = len;
const unsigned char *p = data; const unsigned char *p = data;
int ret = 0;
if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE ) if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
{ {
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512( data, len, tmp, 0 ); if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 )
goto cleanup;
#else #else
mbedtls_sha256( data, len, tmp, 0 ); if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 )
goto cleanup;
#endif #endif
p = tmp; p = tmp;
use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
@ -189,15 +208,35 @@ static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id
header[0] = source_id; header[0] = source_id;
header[1] = use_len & 0xFF; header[1] = use_len & 0xFF;
/*
* Start the accumulator if this has not already happened. Note that
* it is sufficient to start the accumulator here only because all calls to
* gather entropy eventually execute this code.
*/
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_update( &ctx->accumulator, header, 2 ); if( ctx->accumulator_started == 0 &&
mbedtls_sha512_update( &ctx->accumulator, p, use_len ); ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
goto cleanup;
else
ctx->accumulator_started = 1;
if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
goto cleanup;
ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len );
#else #else
mbedtls_sha256_update( &ctx->accumulator, header, 2 ); if( ctx->accumulator_started == 0 &&
mbedtls_sha256_update( &ctx->accumulator, p, use_len ); ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
goto cleanup;
else
ctx->accumulator_started = 1;
if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
goto cleanup;
ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len );
#endif #endif
return( 0 ); cleanup:
mbedtls_zeroize( tmp, sizeof( tmp ) );
return( ret );
} }
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
@ -244,7 +283,7 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx )
if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 ) buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 )
{ {
return( ret ); goto cleanup;
} }
/* /*
@ -252,15 +291,20 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx )
*/ */
if( olen > 0 ) if( olen > 0 )
{ {
entropy_update( ctx, (unsigned char) i, buf, olen ); if( ( ret = entropy_update( ctx, (unsigned char) i,
buf, olen ) ) != 0 )
return( ret );
ctx->source[i].size += olen; ctx->source[i].size += olen;
} }
} }
if( have_one_strong == 0 ) if( have_one_strong == 0 )
return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE ); ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
return( 0 ); cleanup:
mbedtls_zeroize( buf, sizeof( buf ) );
return( ret );
} }
/* /*
@ -335,33 +379,52 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_finish( &ctx->accumulator, buf ); /*
* Note that at this stage it is assumed that the accumulator was started
* in a previous call to entropy_update(). If this is not guaranteed, the
* code below will fail.
*/
if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 )
goto exit;
/* /*
* Reset accumulator and counters and recycle existing entropy * Reset accumulator and counters and recycle existing entropy
*/ */
memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) ); mbedtls_sha512_free( &ctx->accumulator );
mbedtls_sha512_starts( &ctx->accumulator, 0 ); mbedtls_sha512_init( &ctx->accumulator );
mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
goto exit;
if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf,
MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
goto exit;
/* /*
* Perform second SHA-512 on entropy * Perform second SHA-512 on entropy
*/ */
mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ); if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
buf, 0 ) ) != 0 )
goto exit;
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
mbedtls_sha256_finish( &ctx->accumulator, buf ); if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 )
goto exit;
/* /*
* Reset accumulator and counters and recycle existing entropy * Reset accumulator and counters and recycle existing entropy
*/ */
memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) ); mbedtls_sha256_free( &ctx->accumulator );
mbedtls_sha256_starts( &ctx->accumulator, 0 ); mbedtls_sha256_init( &ctx->accumulator );
mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
goto exit;
if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf,
MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
goto exit;
/* /*
* Perform second SHA-256 on entropy * Perform second SHA-256 on entropy
*/ */
mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ); if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
buf, 0 ) ) != 0 )
goto exit;
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
for( i = 0; i < ctx->source_count; i++ ) for( i = 0; i < ctx->source_count; i++ )
@ -372,6 +435,8 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
ret = 0; ret = 0;
exit: exit:
mbedtls_zeroize( buf, sizeof( buf ) );
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
@ -384,7 +449,7 @@ exit:
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
{ {
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
/* Read new seed and write it to NV */ /* Read new seed and write it to NV */
if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
@ -395,9 +460,9 @@ int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
/* Manually update the remaining stream with a separator value to diverge */ /* Manually update the remaining stream with a separator value to diverge */
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
return( 0 ); return( ret );
} }
#endif /* MBEDTLS_ENTROPY_NV_SEED */ #endif /* MBEDTLS_ENTROPY_NV_SEED */
@ -423,12 +488,15 @@ int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *p
ret = 0; ret = 0;
exit: exit:
mbedtls_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( ret ); return( ret );
} }
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ) int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
@ -444,14 +512,16 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *
n = MBEDTLS_ENTROPY_MAX_SEED_SIZE; n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
if( fread( buf, 1, n, f ) != n ) if( fread( buf, 1, n, f ) != n )
{ ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
fclose( f ); else
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); ret = mbedtls_entropy_update_manual( ctx, buf, n );
}
fclose( f ); fclose( f );
mbedtls_entropy_update_manual( ctx, buf, n ); mbedtls_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( mbedtls_entropy_write_seed_file( ctx, path ) ); return( mbedtls_entropy_write_seed_file( ctx, path ) );
} }

View file

@ -47,6 +47,10 @@
#include "mbedtls/aes.h" #include "mbedtls/aes.h"
#endif #endif
#if defined(MBEDTLS_ARC4_C)
#include "mbedtls/arc4.h"
#endif
#if defined(MBEDTLS_BASE64_C) #if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h" #include "mbedtls/base64.h"
#endif #endif
@ -71,6 +75,10 @@
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#endif #endif
#if defined(MBEDTLS_CMAC_C)
#include "mbedtls/cmac.h"
#endif
#if defined(MBEDTLS_CTR_DRBG_C) #if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h" #include "mbedtls/ctr_drbg.h"
#endif #endif
@ -103,6 +111,18 @@
#include "mbedtls/md.h" #include "mbedtls/md.h"
#endif #endif
#if defined(MBEDTLS_MD2_C)
#include "mbedtls/md2.h"
#endif
#if defined(MBEDTLS_MD4_C)
#include "mbedtls/md4.h"
#endif
#if defined(MBEDTLS_MD5_C)
#include "mbedtls/md5.h"
#endif
#if defined(MBEDTLS_NET_C) #if defined(MBEDTLS_NET_C)
#include "mbedtls/net_sockets.h" #include "mbedtls/net_sockets.h"
#endif #endif
@ -131,10 +151,26 @@
#include "mbedtls/pkcs5.h" #include "mbedtls/pkcs5.h"
#endif #endif
#if defined(MBEDTLS_RIPEMD160_C)
#include "mbedtls/ripemd160.h"
#endif
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
#endif #endif
#if defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
#include "mbedtls/sha512.h"
#endif
#if defined(MBEDTLS_SSL_TLS_C) #if defined(MBEDTLS_SSL_TLS_C)
#include "mbedtls/ssl.h" #include "mbedtls/ssl.h"
#endif #endif
@ -176,7 +212,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) ) if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" ); mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) ) if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters to function" ); mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) ) if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" ); mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) ) if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
@ -186,12 +222,14 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) ) if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" ); mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) ) if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid, eg because it was free()ed" ); mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" );
#endif /* MBEDTLS_CIPHER_C */ #endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_DHM_C) #if defined(MBEDTLS_DHM_C)
if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) ) if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters to function" ); mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" );
if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) ) if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" ); mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) ) if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
@ -207,7 +245,11 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) ) if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" ); mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) ) if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "DHM - Read/write of file failed" ); mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" );
#endif /* MBEDTLS_DHM_C */ #endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
@ -226,7 +268,9 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) ) if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" ); mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) ) if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
mbedtls_snprintf( buf, buflen, "ECP - Signature is valid but shorter than the user-supplied length" ); mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - ECP hardware accelerator failed" );
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C) #if defined(MBEDTLS_MD_C)
@ -238,6 +282,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" ); mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) ) if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" ); mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" );
#endif /* MBEDTLS_MD_C */ #endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) #if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
@ -289,7 +335,9 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ) if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) ) if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" ); mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" );
#endif /* MBEDTLS_PK_C */ #endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_PKCS12_C) #if defined(MBEDTLS_PKCS12_C)
@ -322,7 +370,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) ) if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" ); mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) ) if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the library's validity check" ); mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" );
if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) ) if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" ); mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) ) if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
@ -333,6 +381,10 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" ); mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) ) if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" ); mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) )
mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" );
#endif /* MBEDTLS_RSA_C */ #endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SSL_TLS_C) #if defined(MBEDTLS_SSL_TLS_C)
@ -520,8 +572,17 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "AES - Invalid key length" ); mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) ) if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" ); mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" );
#endif /* MBEDTLS_AES_C */ #endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_ARC4_C)
if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
#endif /* MBEDTLS_ARC4_C */
#if defined(MBEDTLS_ASN1_PARSE_C) #if defined(MBEDTLS_ASN1_PARSE_C)
if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) ) if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" ); mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
@ -568,6 +629,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
#if defined(MBEDTLS_BLOWFISH_C) #if defined(MBEDTLS_BLOWFISH_C)
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH) ) if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid key length" ); mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) ) if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" ); mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
#endif /* MBEDTLS_BLOWFISH_C */ #endif /* MBEDTLS_BLOWFISH_C */
@ -577,29 +640,40 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" ); mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) ) if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" ); mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" );
#endif /* MBEDTLS_CAMELLIA_C */ #endif /* MBEDTLS_CAMELLIA_C */
#if defined(MBEDTLS_CCM_C) #if defined(MBEDTLS_CCM_C)
if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) ) if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to function" ); mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" );
if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) ) if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" ); mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" );
#endif /* MBEDTLS_CCM_C */ #endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CMAC_C)
if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" );
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_CTR_DRBG_C) #if defined(MBEDTLS_CTR_DRBG_C)
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) ) if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" ); mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) ) if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" ); mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) ) if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" ); mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) ) if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" ); mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" );
#endif /* MBEDTLS_CTR_DRBG_C */ #endif /* MBEDTLS_CTR_DRBG_C */
#if defined(MBEDTLS_DES_C) #if defined(MBEDTLS_DES_C)
if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) ) if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" ); mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" );
#endif /* MBEDTLS_DES_C */ #endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_ENTROPY_C) #if defined(MBEDTLS_ENTROPY_C)
@ -618,6 +692,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) ) if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" ); mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) ) if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" ); mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
#endif /* MBEDTLS_GCM_C */ #endif /* MBEDTLS_GCM_C */
@ -633,6 +709,21 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" ); mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
#endif /* MBEDTLS_HMAC_DRBG_C */ #endif /* MBEDTLS_HMAC_DRBG_C */
#if defined(MBEDTLS_MD2_C)
if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" );
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" );
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" );
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_NET_C) #if defined(MBEDTLS_NET_C)
if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) ) if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" ); mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
@ -670,6 +761,26 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" ); mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
#endif /* MBEDTLS_PADLOCK_C */ #endif /* MBEDTLS_PADLOCK_C */
#if defined(MBEDTLS_RIPEMD160_C)
if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
#endif /* MBEDTLS_RIPEMD160_C */
#if defined(MBEDTLS_SHA1_C)
if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" );
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" );
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) ) if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" ); mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
@ -682,6 +793,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
#if defined(MBEDTLS_XTEA_C) #if defined(MBEDTLS_XTEA_C)
if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) ) if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" ); mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" );
#endif /* MBEDTLS_XTEA_C */ #endif /* MBEDTLS_XTEA_C */
// END generated code // END generated code

View file

@ -48,6 +48,7 @@
#endif #endif
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
#include "mbedtls/aes.h"
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
@ -56,6 +57,8 @@
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#if !defined(MBEDTLS_GCM_ALT)
/* /*
* 32-bit integer manipulation macros (big endian) * 32-bit integer manipulation macros (big endian)
*/ */
@ -510,6 +513,8 @@ void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
} }
#endif /* !MBEDTLS_GCM_ALT */
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/* /*
* AES-GCM test vectors from: * AES-GCM test vectors from:
@ -746,34 +751,48 @@ int mbedtls_gcm_self_test( int verbose )
int i, j, ret; int i, j, ret;
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
mbedtls_gcm_init( &ctx );
for( j = 0; j < 3; j++ ) for( j = 0; j < 3; j++ )
{ {
int key_len = 128 + 64 * j; int key_len = 128 + 64 * j;
for( i = 0; i < MAX_TESTS; i++ ) for( i = 0; i < MAX_TESTS; i++ )
{ {
mbedtls_gcm_init( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ", mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "enc" ); key_len, i, "enc" );
mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && key_len == 192 )
{
mbedtls_printf( "skipped\n" );
break;
}
else if( ret != 0 )
{
goto exit;
}
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
pt_len[i], pt_len[i],
iv[iv_index[i]], iv_len[i], iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i], additional[add_index[i]], add_len[i],
pt[pt_index[i]], buf, 16, tag_buf ); pt[pt_index[i]], buf, 16, tag_buf );
if( ret != 0 )
goto exit;
if( ret != 0 || if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto exit;
return( 1 );
} }
mbedtls_gcm_free( &ctx ); mbedtls_gcm_free( &ctx );
@ -781,11 +800,16 @@ int mbedtls_gcm_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ", mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "dec" ); key_len, i, "dec" );
mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
pt_len[i], pt_len[i],
@ -793,14 +817,14 @@ int mbedtls_gcm_self_test( int verbose )
additional[add_index[i]], add_len[i], additional[add_index[i]], add_len[i],
ct[j * 6 + i], buf, 16, tag_buf ); ct[j * 6 + i], buf, 16, tag_buf );
if( ret != 0 || if( ret != 0 )
memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || goto exit;
if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto exit;
return( 1 );
} }
mbedtls_gcm_free( &ctx ); mbedtls_gcm_free( &ctx );
@ -808,66 +832,51 @@ int mbedtls_gcm_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "enc" ); key_len, i, "enc" );
mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
iv[iv_index[i]], iv_len[i], iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i] ); additional[add_index[i]], add_len[i] );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
if( pt_len[i] > 32 ) if( pt_len[i] > 32 )
{ {
size_t rest_len = pt_len[i] - 32; size_t rest_len = pt_len[i] - 32;
ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
buf + 32 ); buf + 32 );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
else else
{ {
ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
if( ret != 0 || if( ret != 0 )
memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || goto exit;
if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto exit;
return( 1 );
} }
mbedtls_gcm_free( &ctx ); mbedtls_gcm_free( &ctx );
@ -875,80 +884,75 @@ int mbedtls_gcm_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "dec" ); key_len, i, "dec" );
mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
iv[iv_index[i]], iv_len[i], iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i] ); additional[add_index[i]], add_len[i] );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
if( pt_len[i] > 32 ) if( pt_len[i] > 32 )
{ {
size_t rest_len = pt_len[i] - 32; size_t rest_len = pt_len[i] - 32;
ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
buf + 32 ); buf + 32 );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
else else
{ {
ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf ); ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
buf );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
if( ret != 0 || if( ret != 0 )
memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || goto exit;
if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto exit;
return( 1 );
} }
mbedtls_gcm_free( &ctx ); mbedtls_gcm_free( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
} }
} }
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
return( 0 ); ret = 0;
exit:
if( ret != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
mbedtls_gcm_free( &ctx );
}
return( ret );
} }
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */

View file

@ -366,11 +366,14 @@ int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const cha
exit: exit:
fclose( f ); fclose( f );
mbedtls_zeroize( buf, sizeof( buf ) );
return( ret ); return( ret );
} }
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
@ -389,15 +392,17 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch
} }
if( fread( buf, 1, n, f ) != n ) if( fread( buf, 1, n, f ) != n )
{ ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
fclose( f ); else
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
}
fclose( f );
mbedtls_hmac_drbg_update( ctx, buf, n ); mbedtls_hmac_drbg_update( ctx, buf, n );
fclose( f );
mbedtls_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
} }
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */

View file

@ -252,9 +252,7 @@ int mbedtls_md_starts( mbedtls_md_context_t *ctx )
if( ctx == NULL || ctx->md_info == NULL ) if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->starts_func( ctx->md_ctx ); return( ctx->md_info->starts_func( ctx->md_ctx ) );
return( 0 );
} }
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@ -262,9 +260,7 @@ int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, si
if( ctx == NULL || ctx->md_info == NULL ) if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->update_func( ctx->md_ctx, input, ilen ); return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
return( 0 );
} }
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@ -272,9 +268,7 @@ int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
if( ctx == NULL || ctx->md_info == NULL ) if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->finish_func( ctx->md_ctx, output ); return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
return( 0 );
} }
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
@ -283,9 +277,7 @@ int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, si
if( md_info == NULL ) if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info->digest_func( input, ilen, output ); return( md_info->digest_func( input, ilen, output ) );
return( 0 );
} }
#if defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_FS_IO)
@ -308,20 +300,20 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigne
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
goto cleanup; goto cleanup;
md_info->starts_func( ctx.md_ctx ); if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
goto cleanup;
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md_info->update_func( ctx.md_ctx, buf, n ); if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
goto cleanup;
if( ferror( f ) != 0 ) if( ferror( f ) != 0 )
{
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
goto cleanup; else
} ret = md_info->finish_func( ctx.md_ctx, output );
md_info->finish_func( ctx.md_ctx, output );
cleanup: cleanup:
mbedtls_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
mbedtls_md_free( &ctx ); mbedtls_md_free( &ctx );
@ -331,6 +323,7 @@ cleanup:
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
{ {
int ret;
unsigned char sum[MBEDTLS_MD_MAX_SIZE]; unsigned char sum[MBEDTLS_MD_MAX_SIZE];
unsigned char *ipad, *opad; unsigned char *ipad, *opad;
size_t i; size_t i;
@ -340,9 +333,12 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
if( keylen > (size_t) ctx->md_info->block_size ) if( keylen > (size_t) ctx->md_info->block_size )
{ {
ctx->md_info->starts_func( ctx->md_ctx ); if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
ctx->md_info->update_func( ctx->md_ctx, key, keylen ); goto cleanup;
ctx->md_info->finish_func( ctx->md_ctx, sum ); if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
goto cleanup;
if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
goto cleanup;
keylen = ctx->md_info->size; keylen = ctx->md_info->size;
key = sum; key = sum;
@ -360,12 +356,16 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
opad[i] = (unsigned char)( opad[i] ^ key[i] ); opad[i] = (unsigned char)( opad[i] ^ key[i] );
} }
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
goto cleanup;
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
ctx->md_info->block_size ) ) != 0 )
goto cleanup;
cleanup:
mbedtls_zeroize( sum, sizeof( sum ) ); mbedtls_zeroize( sum, sizeof( sum ) );
ctx->md_info->starts_func( ctx->md_ctx ); return( ret );
ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
return( 0 );
} }
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@ -373,13 +373,12 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->update_func( ctx->md_ctx, input, ilen ); return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
return( 0 );
} }
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{ {
int ret;
unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
unsigned char *opad; unsigned char *opad;
@ -388,17 +387,22 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
ctx->md_info->finish_func( ctx->md_ctx, tmp ); if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
ctx->md_info->starts_func( ctx->md_ctx ); return( ret );
ctx->md_info->update_func( ctx->md_ctx, opad, ctx->md_info->block_size ); if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
ctx->md_info->update_func( ctx->md_ctx, tmp, ctx->md_info->size ); return( ret );
ctx->md_info->finish_func( ctx->md_ctx, output ); if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
ctx->md_info->block_size ) ) != 0 )
return( 0 ); return( ret );
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
ctx->md_info->size ) ) != 0 )
return( ret );
return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
} }
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
{ {
int ret;
unsigned char *ipad; unsigned char *ipad;
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
@ -406,13 +410,14 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
ipad = (unsigned char *) ctx->hmac_ctx; ipad = (unsigned char *) ctx->hmac_ctx;
ctx->md_info->starts_func( ctx->md_ctx ); if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size ); return( ret );
return( ctx->md_info->update_func( ctx->md_ctx, ipad,
return( 0 ); ctx->md_info->block_size ) );
} }
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen, const unsigned char *input, size_t ilen,
unsigned char *output ) unsigned char *output )
{ {
@ -425,15 +430,19 @@ int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key,
mbedtls_md_init( &ctx ); mbedtls_md_init( &ctx );
if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
return( ret ); goto cleanup;
mbedtls_md_hmac_starts( &ctx, key, keylen ); if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
mbedtls_md_hmac_update( &ctx, input, ilen ); goto cleanup;
mbedtls_md_hmac_finish( &ctx, output ); if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
goto cleanup;
cleanup:
mbedtls_md_free( &ctx ); mbedtls_md_free( &ctx );
return( 0 ); return( ret );
} }
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
@ -441,9 +450,7 @@ int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
if( ctx == NULL || ctx->md_info == NULL ) if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->process_func( ctx->md_ctx, data ); return( ctx->md_info->process_func( ctx->md_ctx, data ) );
return( 0 );
} }
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )

View file

@ -107,16 +107,25 @@ void mbedtls_md2_clone( mbedtls_md2_context *dst,
/* /*
* MD2 context setup * MD2 context setup
*/ */
void mbedtls_md2_starts( mbedtls_md2_context *ctx ) int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx )
{ {
memset( ctx->cksum, 0, 16 ); memset( ctx->cksum, 0, 16 );
memset( ctx->state, 0, 46 ); memset( ctx->state, 0, 46 );
memset( ctx->buffer, 0, 16 ); memset( ctx->buffer, 0, 16 );
ctx->left = 0; ctx->left = 0;
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_starts( mbedtls_md2_context *ctx )
{
mbedtls_md2_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_MD2_PROCESS_ALT) #if !defined(MBEDTLS_MD2_PROCESS_ALT)
void mbedtls_md2_process( mbedtls_md2_context *ctx ) int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
{ {
int i, j; int i, j;
unsigned char t = 0; unsigned char t = 0;
@ -148,14 +157,26 @@ void mbedtls_md2_process( mbedtls_md2_context *ctx )
( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] ); ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
t = ctx->cksum[i]; t = ctx->cksum[i];
} }
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_process( mbedtls_md2_context *ctx )
{
mbedtls_internal_md2_process( ctx );
}
#endif
#endif /* !MBEDTLS_MD2_PROCESS_ALT */ #endif /* !MBEDTLS_MD2_PROCESS_ALT */
/* /*
* MD2 process buffer * MD2 process buffer
*/ */
void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, size_t ilen ) int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen )
{ {
int ret;
size_t fill; size_t fill;
while( ilen > 0 ) while( ilen > 0 )
@ -174,16 +195,30 @@ void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, s
if( ctx->left == 16 ) if( ctx->left == 16 )
{ {
ctx->left = 0; ctx->left = 0;
mbedtls_md2_process( ctx ); if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
return( ret );
} }
} }
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_update( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_md2_update_ret( ctx, input, ilen );
}
#endif
/* /*
* MD2 final digest * MD2 final digest
*/ */
void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] ) int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
unsigned char output[16] )
{ {
int ret;
size_t i; size_t i;
unsigned char x; unsigned char x;
@ -192,36 +227,70 @@ void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] )
for( i = ctx->left; i < 16; i++ ) for( i = ctx->left; i < 16; i++ )
ctx->buffer[i] = x; ctx->buffer[i] = x;
mbedtls_md2_process( ctx ); if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
return( ret );
memcpy( ctx->buffer, ctx->cksum, 16 ); memcpy( ctx->buffer, ctx->cksum, 16 );
mbedtls_md2_process( ctx ); if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
return( ret );
memcpy( output, ctx->state, 16 ); memcpy( output, ctx->state, 16 );
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2_finish( mbedtls_md2_context *ctx,
unsigned char output[16] )
{
mbedtls_md2_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_MD2_ALT */ #endif /* !MBEDTLS_MD2_ALT */
/* /*
* output = MD2( input buffer ) * output = MD2( input buffer )
*/ */
void mbedtls_md2( const unsigned char *input, size_t ilen, unsigned char output[16] ) int mbedtls_md2_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{ {
int ret;
mbedtls_md2_context ctx; mbedtls_md2_context ctx;
mbedtls_md2_init( &ctx ); mbedtls_md2_init( &ctx );
mbedtls_md2_starts( &ctx );
mbedtls_md2_update( &ctx, input, ilen ); if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 )
mbedtls_md2_finish( &ctx, output ); goto exit;
if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_md2_free( &ctx ); mbedtls_md2_free( &ctx );
return( ret );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md2( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
mbedtls_md2_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* RFC 1319 test vectors * RFC 1319 test vectors
*/ */
static const char md2_test_str[7][81] = static const unsigned char md2_test_str[7][81] =
{ {
{ "" }, { "" },
{ "a" }, { "a" },
@ -229,10 +298,15 @@ static const char md2_test_str[7][81] =
{ "message digest" }, { "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" }, { "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \ { "12345678901234567890123456789012345678901234567890123456789012"
"345678901234567890" } "345678901234567890" }
}; };
static const size_t md2_test_strlen[7] =
{
0, 1, 3, 14, 26, 62, 80
};
static const unsigned char md2_test_sum[7][16] = static const unsigned char md2_test_sum[7][16] =
{ {
{ 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D, { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
@ -256,7 +330,7 @@ static const unsigned char md2_test_sum[7][16] =
*/ */
int mbedtls_md2_self_test( int verbose ) int mbedtls_md2_self_test( int verbose )
{ {
int i; int i, ret = 0;
unsigned char md2sum[16]; unsigned char md2sum[16];
for( i = 0; i < 7; i++ ) for( i = 0; i < 7; i++ )
@ -264,15 +338,14 @@ int mbedtls_md2_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " MD2 test #%d: ", i + 1 ); mbedtls_printf( " MD2 test #%d: ", i + 1 );
mbedtls_md2( (unsigned char *) md2_test_str[i], ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum );
strlen( md2_test_str[i] ), md2sum ); if( ret != 0 )
goto fail;
if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 ) if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto fail;
return( 1 );
} }
if( verbose != 0 ) if( verbose != 0 )
@ -283,6 +356,12 @@ int mbedtls_md2_self_test( int verbose )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
return( 0 ); return( 0 );
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
} }
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */

View file

@ -100,7 +100,7 @@ void mbedtls_md4_clone( mbedtls_md4_context *dst,
/* /*
* MD4 context setup * MD4 context setup
*/ */
void mbedtls_md4_starts( mbedtls_md4_context *ctx ) int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
{ {
ctx->total[0] = 0; ctx->total[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
@ -109,10 +109,20 @@ void mbedtls_md4_starts( mbedtls_md4_context *ctx )
ctx->state[1] = 0xEFCDAB89; ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE; ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476; ctx->state[3] = 0x10325476;
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_starts( mbedtls_md4_context *ctx )
{
mbedtls_md4_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_MD4_PROCESS_ALT) #if !defined(MBEDTLS_MD4_PROCESS_ALT)
void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] ) int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] )
{ {
uint32_t X[16], A, B, C, D; uint32_t X[16], A, B, C, D;
@ -213,19 +223,32 @@ void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64]
ctx->state[1] += B; ctx->state[1] += B;
ctx->state[2] += C; ctx->state[2] += C;
ctx->state[3] += D; ctx->state[3] += D;
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_md4_process( ctx, data );
}
#endif
#endif /* !MBEDTLS_MD4_PROCESS_ALT */ #endif /* !MBEDTLS_MD4_PROCESS_ALT */
/* /*
* MD4 process buffer * MD4 process buffer
*/ */
void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, size_t ilen ) int mbedtls_md4_update_ret( mbedtls_md4_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;
@ -240,7 +263,10 @@ void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, s
{ {
memcpy( (void *) (ctx->buffer + left), memcpy( (void *) (ctx->buffer + left),
(void *) input, fill ); (void *) input, fill );
mbedtls_md4_process( ctx, ctx->buffer );
if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
input += fill; input += fill;
ilen -= fill; ilen -= fill;
left = 0; left = 0;
@ -248,7 +274,9 @@ void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, s
while( ilen >= 64 ) while( ilen >= 64 )
{ {
mbedtls_md4_process( ctx, input ); if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
return( ret );
input += 64; input += 64;
ilen -= 64; ilen -= 64;
} }
@ -258,8 +286,19 @@ void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, s
memcpy( (void *) (ctx->buffer + left), memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen ); (void *) input, ilen );
} }
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_update( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_md4_update_ret( ctx, input, ilen );
}
#endif
static const unsigned char md4_padding[64] = static const unsigned char md4_padding[64] =
{ {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -271,8 +310,10 @@ static const unsigned char md4_padding[64] =
/* /*
* MD4 final digest * MD4 final digest
*/ */
void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] ) int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
unsigned char output[16] )
{ {
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];
@ -287,37 +328,74 @@ void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] )
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_md4_update( ctx, (unsigned char *) md4_padding, padn ); ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
mbedtls_md4_update( ctx, msglen, 8 ); if( ret != 0 )
return( ret );
if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
return( ret );
PUT_UINT32_LE( ctx->state[0], output, 0 ); PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 ); PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 ); PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 ); PUT_UINT32_LE( ctx->state[3], output, 12 );
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4_finish( mbedtls_md4_context *ctx,
unsigned char output[16] )
{
mbedtls_md4_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_MD4_ALT */ #endif /* !MBEDTLS_MD4_ALT */
/* /*
* output = MD4( input buffer ) * output = MD4( input buffer )
*/ */
void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) int mbedtls_md4_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{ {
int ret;
mbedtls_md4_context ctx; mbedtls_md4_context ctx;
mbedtls_md4_init( &ctx ); mbedtls_md4_init( &ctx );
mbedtls_md4_starts( &ctx );
mbedtls_md4_update( &ctx, input, ilen ); if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
mbedtls_md4_finish( &ctx, output ); goto exit;
if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_md4_free( &ctx ); mbedtls_md4_free( &ctx );
return( ret );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md4( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
mbedtls_md4_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* RFC 1320 test vectors * RFC 1320 test vectors
*/ */
static const char md4_test_str[7][81] = static const unsigned char md4_test_str[7][81] =
{ {
{ "" }, { "" },
{ "a" }, { "a" },
@ -325,10 +403,15 @@ static const char md4_test_str[7][81] =
{ "message digest" }, { "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" }, { "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \ { "12345678901234567890123456789012345678901234567890123456789012"
"345678901234567890" } "345678901234567890" }
}; };
static const size_t md4_test_strlen[7] =
{
0, 1, 3, 14, 26, 62, 80
};
static const unsigned char md4_test_sum[7][16] = static const unsigned char md4_test_sum[7][16] =
{ {
{ 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
@ -352,7 +435,7 @@ static const unsigned char md4_test_sum[7][16] =
*/ */
int mbedtls_md4_self_test( int verbose ) int mbedtls_md4_self_test( int verbose )
{ {
int i; int i, ret = 0;
unsigned char md4sum[16]; unsigned char md4sum[16];
for( i = 0; i < 7; i++ ) for( i = 0; i < 7; i++ )
@ -360,15 +443,14 @@ int mbedtls_md4_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " MD4 test #%d: ", i + 1 ); mbedtls_printf( " MD4 test #%d: ", i + 1 );
mbedtls_md4( (unsigned char *) md4_test_str[i], ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
strlen( md4_test_str[i] ), md4sum ); if( ret != 0 )
goto fail;
if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto fail;
return( 1 );
} }
if( verbose != 0 ) if( verbose != 0 )
@ -379,6 +461,12 @@ int mbedtls_md4_self_test( int verbose )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
return( 0 ); return( 0 );
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
} }
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */

View file

@ -99,7 +99,7 @@ void mbedtls_md5_clone( mbedtls_md5_context *dst,
/* /*
* MD5 context setup * MD5 context setup
*/ */
void mbedtls_md5_starts( mbedtls_md5_context *ctx ) int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx )
{ {
ctx->total[0] = 0; ctx->total[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
@ -108,10 +108,20 @@ void mbedtls_md5_starts( mbedtls_md5_context *ctx )
ctx->state[1] = 0xEFCDAB89; ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE; ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476; ctx->state[3] = 0x10325476;
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5_starts( mbedtls_md5_context *ctx )
{
mbedtls_md5_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_MD5_PROCESS_ALT) #if !defined(MBEDTLS_MD5_PROCESS_ALT)
void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ) int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] )
{ {
uint32_t X[16], A, B, C, D; uint32_t X[16], A, B, C, D;
@ -232,19 +242,32 @@ void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64]
ctx->state[1] += B; ctx->state[1] += B;
ctx->state[2] += C; ctx->state[2] += C;
ctx->state[3] += D; ctx->state[3] += D;
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_md5_process( ctx, data );
}
#endif
#endif /* !MBEDTLS_MD5_PROCESS_ALT */ #endif /* !MBEDTLS_MD5_PROCESS_ALT */
/* /*
* MD5 process buffer * MD5 process buffer
*/ */
void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen ) int mbedtls_md5_update_ret( mbedtls_md5_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;
@ -258,7 +281,9 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, s
if( left && ilen >= fill ) if( left && ilen >= fill )
{ {
memcpy( (void *) (ctx->buffer + left), input, fill ); memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_md5_process( ctx, ctx->buffer ); if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
input += fill; input += fill;
ilen -= fill; ilen -= fill;
left = 0; left = 0;
@ -266,7 +291,9 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, s
while( ilen >= 64 ) while( ilen >= 64 )
{ {
mbedtls_md5_process( ctx, input ); if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 )
return( ret );
input += 64; input += 64;
ilen -= 64; ilen -= 64;
} }
@ -275,60 +302,122 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, s
{ {
memcpy( (void *) (ctx->buffer + left), input, ilen ); memcpy( (void *) (ctx->buffer + left), input, ilen );
} }
return( 0 );
} }
static const unsigned char md5_padding[64] = #if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5_update( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen )
{ {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, mbedtls_md5_update_ret( ctx, input, ilen );
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* /*
* MD5 final digest * MD5 final digest
*/ */
void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ) int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
unsigned char output[16] )
{ {
uint32_t last, padn; int ret;
uint32_t used;
uint32_t high, low; uint32_t high, low;
unsigned char msglen[8];
/*
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
*/
used = ctx->total[0] & 0x3F;
ctx->buffer[used++] = 0x80;
if( used <= 56 )
{
/* Enough room for padding + length in current block */
memset( ctx->buffer + used, 0, 56 - used );
}
else
{
/* We'll need an extra block */
memset( ctx->buffer + used, 0, 64 - used );
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
memset( ctx->buffer, 0, 56 );
}
/*
* Add message length
*/
high = ( ctx->total[0] >> 29 ) high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 ); | ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 ); low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, msglen, 0 ); PUT_UINT32_LE( low, ctx->buffer, 56 );
PUT_UINT32_LE( high, msglen, 4 ); PUT_UINT32_LE( high, ctx->buffer, 60 );
last = ctx->total[0] & 0x3F; if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); return( ret );
mbedtls_md5_update( ctx, md5_padding, padn );
mbedtls_md5_update( ctx, msglen, 8 );
/*
* Output final state
*/
PUT_UINT32_LE( ctx->state[0], output, 0 ); PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 ); PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 ); PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 ); PUT_UINT32_LE( ctx->state[3], output, 12 );
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5_finish( mbedtls_md5_context *ctx,
unsigned char output[16] )
{
mbedtls_md5_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_MD5_ALT */ #endif /* !MBEDTLS_MD5_ALT */
/* /*
* output = MD5( input buffer ) * output = MD5( input buffer )
*/ */
void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) int mbedtls_md5_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{ {
int ret;
mbedtls_md5_context ctx; mbedtls_md5_context ctx;
mbedtls_md5_init( &ctx ); mbedtls_md5_init( &ctx );
mbedtls_md5_starts( &ctx );
mbedtls_md5_update( &ctx, input, ilen ); if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 )
mbedtls_md5_finish( &ctx, output ); goto exit;
if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_md5_free( &ctx ); mbedtls_md5_free( &ctx );
return( ret );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_md5( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
mbedtls_md5_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* RFC 1321 test vectors * RFC 1321 test vectors
@ -341,11 +430,11 @@ static const unsigned char md5_test_buf[7][81] =
{ "message digest" }, { "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" }, { "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \ { "12345678901234567890123456789012345678901234567890123456789012"
"345678901234567890" } "345678901234567890" }
}; };
static const int md5_test_buflen[7] = static const size_t md5_test_buflen[7] =
{ {
0, 1, 3, 14, 26, 62, 80 0, 1, 3, 14, 26, 62, 80
}; };
@ -373,7 +462,7 @@ static const unsigned char md5_test_sum[7][16] =
*/ */
int mbedtls_md5_self_test( int verbose ) int mbedtls_md5_self_test( int verbose )
{ {
int i; int i, ret = 0;
unsigned char md5sum[16]; unsigned char md5sum[16];
for( i = 0; i < 7; i++ ) for( i = 0; i < 7; i++ )
@ -381,14 +470,14 @@ int mbedtls_md5_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " MD5 test #%d: ", i + 1 ); mbedtls_printf( " MD5 test #%d: ", i + 1 );
mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum );
if( ret != 0 )
goto fail;
if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto fail;
return( 1 );
} }
if( verbose != 0 ) if( verbose != 0 )
@ -399,6 +488,12 @@ int mbedtls_md5_self_test( int verbose )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
return( 0 ); return( 0 );
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
} }
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */

View file

@ -73,20 +73,20 @@
#if defined(MBEDTLS_MD2_C) #if defined(MBEDTLS_MD2_C)
static void md2_starts_wrap( void *ctx ) static int md2_starts_wrap( void *ctx )
{ {
mbedtls_md2_starts( (mbedtls_md2_context *) ctx ); return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
} }
static void md2_update_wrap( void *ctx, const unsigned char *input, static int md2_update_wrap( void *ctx, const unsigned char *input,
size_t ilen ) size_t ilen )
{ {
mbedtls_md2_update( (mbedtls_md2_context *) ctx, input, ilen ); return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
} }
static void md2_finish_wrap( void *ctx, unsigned char *output ) static int md2_finish_wrap( void *ctx, unsigned char *output )
{ {
mbedtls_md2_finish( (mbedtls_md2_context *) ctx, output ); return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
} }
static void *md2_ctx_alloc( void ) static void *md2_ctx_alloc( void )
@ -111,11 +111,11 @@ static void md2_clone_wrap( void *dst, const void *src )
(const mbedtls_md2_context *) src ); (const mbedtls_md2_context *) src );
} }
static void md2_process_wrap( void *ctx, const unsigned char *data ) static int md2_process_wrap( void *ctx, const unsigned char *data )
{ {
((void) data); ((void) data);
mbedtls_md2_process( (mbedtls_md2_context *) ctx ); return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
} }
const mbedtls_md_info_t mbedtls_md2_info = { const mbedtls_md_info_t mbedtls_md2_info = {
@ -126,7 +126,7 @@ const mbedtls_md_info_t mbedtls_md2_info = {
md2_starts_wrap, md2_starts_wrap,
md2_update_wrap, md2_update_wrap,
md2_finish_wrap, md2_finish_wrap,
mbedtls_md2, mbedtls_md2_ret,
md2_ctx_alloc, md2_ctx_alloc,
md2_ctx_free, md2_ctx_free,
md2_clone_wrap, md2_clone_wrap,
@ -137,20 +137,20 @@ const mbedtls_md_info_t mbedtls_md2_info = {
#if defined(MBEDTLS_MD4_C) #if defined(MBEDTLS_MD4_C)
static void md4_starts_wrap( void *ctx ) static int md4_starts_wrap( void *ctx )
{ {
mbedtls_md4_starts( (mbedtls_md4_context *) ctx ); return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
} }
static void md4_update_wrap( void *ctx, const unsigned char *input, static int md4_update_wrap( void *ctx, const unsigned char *input,
size_t ilen ) size_t ilen )
{ {
mbedtls_md4_update( (mbedtls_md4_context *) ctx, input, ilen ); return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
} }
static void md4_finish_wrap( void *ctx, unsigned char *output ) static int md4_finish_wrap( void *ctx, unsigned char *output )
{ {
mbedtls_md4_finish( (mbedtls_md4_context *) ctx, output ); return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
} }
static void *md4_ctx_alloc( void ) static void *md4_ctx_alloc( void )
@ -175,9 +175,9 @@ static void md4_clone_wrap( void *dst, const void *src )
(const mbedtls_md4_context *) src ); (const mbedtls_md4_context *) src );
} }
static void md4_process_wrap( void *ctx, const unsigned char *data ) static int md4_process_wrap( void *ctx, const unsigned char *data )
{ {
mbedtls_md4_process( (mbedtls_md4_context *) ctx, data ); return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
} }
const mbedtls_md_info_t mbedtls_md4_info = { const mbedtls_md_info_t mbedtls_md4_info = {
@ -188,7 +188,7 @@ const mbedtls_md_info_t mbedtls_md4_info = {
md4_starts_wrap, md4_starts_wrap,
md4_update_wrap, md4_update_wrap,
md4_finish_wrap, md4_finish_wrap,
mbedtls_md4, mbedtls_md4_ret,
md4_ctx_alloc, md4_ctx_alloc,
md4_ctx_free, md4_ctx_free,
md4_clone_wrap, md4_clone_wrap,
@ -199,20 +199,20 @@ const mbedtls_md_info_t mbedtls_md4_info = {
#if defined(MBEDTLS_MD5_C) #if defined(MBEDTLS_MD5_C)
static void md5_starts_wrap( void *ctx ) static int md5_starts_wrap( void *ctx )
{ {
mbedtls_md5_starts( (mbedtls_md5_context *) ctx ); return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
} }
static void md5_update_wrap( void *ctx, const unsigned char *input, static int md5_update_wrap( void *ctx, const unsigned char *input,
size_t ilen ) size_t ilen )
{ {
mbedtls_md5_update( (mbedtls_md5_context *) ctx, input, ilen ); return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
} }
static void md5_finish_wrap( void *ctx, unsigned char *output ) static int md5_finish_wrap( void *ctx, unsigned char *output )
{ {
mbedtls_md5_finish( (mbedtls_md5_context *) ctx, output ); return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
} }
static void *md5_ctx_alloc( void ) static void *md5_ctx_alloc( void )
@ -237,9 +237,9 @@ static void md5_clone_wrap( void *dst, const void *src )
(const mbedtls_md5_context *) src ); (const mbedtls_md5_context *) src );
} }
static void md5_process_wrap( void *ctx, const unsigned char *data ) static int md5_process_wrap( void *ctx, const unsigned char *data )
{ {
mbedtls_md5_process( (mbedtls_md5_context *) ctx, data ); return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
} }
const mbedtls_md_info_t mbedtls_md5_info = { const mbedtls_md_info_t mbedtls_md5_info = {
@ -250,7 +250,7 @@ const mbedtls_md_info_t mbedtls_md5_info = {
md5_starts_wrap, md5_starts_wrap,
md5_update_wrap, md5_update_wrap,
md5_finish_wrap, md5_finish_wrap,
mbedtls_md5, mbedtls_md5_ret,
md5_ctx_alloc, md5_ctx_alloc,
md5_ctx_free, md5_ctx_free,
md5_clone_wrap, md5_clone_wrap,
@ -261,20 +261,22 @@ const mbedtls_md_info_t mbedtls_md5_info = {
#if defined(MBEDTLS_RIPEMD160_C) #if defined(MBEDTLS_RIPEMD160_C)
static void ripemd160_starts_wrap( void *ctx ) static int ripemd160_starts_wrap( void *ctx )
{ {
mbedtls_ripemd160_starts( (mbedtls_ripemd160_context *) ctx ); return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
} }
static void ripemd160_update_wrap( void *ctx, const unsigned char *input, static int ripemd160_update_wrap( void *ctx, const unsigned char *input,
size_t ilen ) size_t ilen )
{ {
mbedtls_ripemd160_update( (mbedtls_ripemd160_context *) ctx, input, ilen ); return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
input, ilen ) );
} }
static void ripemd160_finish_wrap( void *ctx, unsigned char *output ) static int ripemd160_finish_wrap( void *ctx, unsigned char *output )
{ {
mbedtls_ripemd160_finish( (mbedtls_ripemd160_context *) ctx, output ); return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
output ) );
} }
static void *ripemd160_ctx_alloc( void ) static void *ripemd160_ctx_alloc( void )
@ -299,9 +301,10 @@ static void ripemd160_clone_wrap( void *dst, const void *src )
(const mbedtls_ripemd160_context *) src ); (const mbedtls_ripemd160_context *) src );
} }
static void ripemd160_process_wrap( void *ctx, const unsigned char *data ) static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
{ {
mbedtls_ripemd160_process( (mbedtls_ripemd160_context *) ctx, data ); return( mbedtls_internal_ripemd160_process(
(mbedtls_ripemd160_context *) ctx, data ) );
} }
const mbedtls_md_info_t mbedtls_ripemd160_info = { const mbedtls_md_info_t mbedtls_ripemd160_info = {
@ -312,7 +315,7 @@ const mbedtls_md_info_t mbedtls_ripemd160_info = {
ripemd160_starts_wrap, ripemd160_starts_wrap,
ripemd160_update_wrap, ripemd160_update_wrap,
ripemd160_finish_wrap, ripemd160_finish_wrap,
mbedtls_ripemd160, mbedtls_ripemd160_ret,
ripemd160_ctx_alloc, ripemd160_ctx_alloc,
ripemd160_ctx_free, ripemd160_ctx_free,
ripemd160_clone_wrap, ripemd160_clone_wrap,
@ -323,20 +326,21 @@ const mbedtls_md_info_t mbedtls_ripemd160_info = {
#if defined(MBEDTLS_SHA1_C) #if defined(MBEDTLS_SHA1_C)
static void sha1_starts_wrap( void *ctx ) static int sha1_starts_wrap( void *ctx )
{ {
mbedtls_sha1_starts( (mbedtls_sha1_context *) ctx ); return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
} }
static void sha1_update_wrap( void *ctx, const unsigned char *input, static int sha1_update_wrap( void *ctx, const unsigned char *input,
size_t ilen ) size_t ilen )
{ {
mbedtls_sha1_update( (mbedtls_sha1_context *) ctx, input, ilen ); return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
input, ilen ) );
} }
static void sha1_finish_wrap( void *ctx, unsigned char *output ) static int sha1_finish_wrap( void *ctx, unsigned char *output )
{ {
mbedtls_sha1_finish( (mbedtls_sha1_context *) ctx, output ); return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
} }
static void *sha1_ctx_alloc( void ) static void *sha1_ctx_alloc( void )
@ -361,9 +365,10 @@ static void sha1_ctx_free( void *ctx )
mbedtls_free( ctx ); mbedtls_free( ctx );
} }
static void sha1_process_wrap( void *ctx, const unsigned char *data ) static int sha1_process_wrap( void *ctx, const unsigned char *data )
{ {
mbedtls_sha1_process( (mbedtls_sha1_context *) ctx, data ); return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
data ) );
} }
const mbedtls_md_info_t mbedtls_sha1_info = { const mbedtls_md_info_t mbedtls_sha1_info = {
@ -374,7 +379,7 @@ const mbedtls_md_info_t mbedtls_sha1_info = {
sha1_starts_wrap, sha1_starts_wrap,
sha1_update_wrap, sha1_update_wrap,
sha1_finish_wrap, sha1_finish_wrap,
mbedtls_sha1, mbedtls_sha1_ret,
sha1_ctx_alloc, sha1_ctx_alloc,
sha1_ctx_free, sha1_ctx_free,
sha1_clone_wrap, sha1_clone_wrap,
@ -388,26 +393,28 @@ const mbedtls_md_info_t mbedtls_sha1_info = {
*/ */
#if defined(MBEDTLS_SHA256_C) #if defined(MBEDTLS_SHA256_C)
static void sha224_starts_wrap( void *ctx ) static int sha224_starts_wrap( void *ctx )
{ {
mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 1 ); return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
} }
static void sha224_update_wrap( void *ctx, const unsigned char *input, static int sha224_update_wrap( void *ctx, const unsigned char *input,
size_t ilen ) size_t ilen )
{ {
mbedtls_sha256_update( (mbedtls_sha256_context *) ctx, input, ilen ); return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
input, ilen ) );
} }
static void sha224_finish_wrap( void *ctx, unsigned char *output ) static int sha224_finish_wrap( void *ctx, unsigned char *output )
{ {
mbedtls_sha256_finish( (mbedtls_sha256_context *) ctx, output ); return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
output ) );
} }
static void sha224_wrap( const unsigned char *input, size_t ilen, static int sha224_wrap( const unsigned char *input, size_t ilen,
unsigned char *output ) unsigned char *output )
{ {
mbedtls_sha256( input, ilen, output, 1 ); return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
} }
static void *sha224_ctx_alloc( void ) static void *sha224_ctx_alloc( void )
@ -432,9 +439,10 @@ static void sha224_clone_wrap( void *dst, const void *src )
(const mbedtls_sha256_context *) src ); (const mbedtls_sha256_context *) src );
} }
static void sha224_process_wrap( void *ctx, const unsigned char *data ) static int sha224_process_wrap( void *ctx, const unsigned char *data )
{ {
mbedtls_sha256_process( (mbedtls_sha256_context *) ctx, data ); return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
data ) );
} }
const mbedtls_md_info_t mbedtls_sha224_info = { const mbedtls_md_info_t mbedtls_sha224_info = {
@ -452,15 +460,15 @@ const mbedtls_md_info_t mbedtls_sha224_info = {
sha224_process_wrap, sha224_process_wrap,
}; };
static void sha256_starts_wrap( void *ctx ) static int sha256_starts_wrap( void *ctx )
{ {
mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 0 ); return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
} }
static void sha256_wrap( const unsigned char *input, size_t ilen, static int sha256_wrap( const unsigned char *input, size_t ilen,
unsigned char *output ) unsigned char *output )
{ {
mbedtls_sha256( input, ilen, output, 0 ); return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
} }
const mbedtls_md_info_t mbedtls_sha256_info = { const mbedtls_md_info_t mbedtls_sha256_info = {
@ -482,26 +490,28 @@ const mbedtls_md_info_t mbedtls_sha256_info = {
#if defined(MBEDTLS_SHA512_C) #if defined(MBEDTLS_SHA512_C)
static void sha384_starts_wrap( void *ctx ) static int sha384_starts_wrap( void *ctx )
{ {
mbedtls_sha512_starts( (mbedtls_sha512_context *) ctx, 1 ); return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
} }
static void sha384_update_wrap( void *ctx, const unsigned char *input, static int sha384_update_wrap( void *ctx, const unsigned char *input,
size_t ilen ) size_t ilen )
{ {
mbedtls_sha512_update( (mbedtls_sha512_context *) ctx, input, ilen ); return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
input, ilen ) );
} }
static void sha384_finish_wrap( void *ctx, unsigned char *output ) static int sha384_finish_wrap( void *ctx, unsigned char *output )
{ {
mbedtls_sha512_finish( (mbedtls_sha512_context *) ctx, output ); return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
output ) );
} }
static void sha384_wrap( const unsigned char *input, size_t ilen, static int sha384_wrap( const unsigned char *input, size_t ilen,
unsigned char *output ) unsigned char *output )
{ {
mbedtls_sha512( input, ilen, output, 1 ); return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
} }
static void *sha384_ctx_alloc( void ) static void *sha384_ctx_alloc( void )
@ -526,9 +536,10 @@ static void sha384_clone_wrap( void *dst, const void *src )
(const mbedtls_sha512_context *) src ); (const mbedtls_sha512_context *) src );
} }
static void sha384_process_wrap( void *ctx, const unsigned char *data ) static int sha384_process_wrap( void *ctx, const unsigned char *data )
{ {
mbedtls_sha512_process( (mbedtls_sha512_context *) ctx, data ); return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
data ) );
} }
const mbedtls_md_info_t mbedtls_sha384_info = { const mbedtls_md_info_t mbedtls_sha384_info = {
@ -546,15 +557,15 @@ const mbedtls_md_info_t mbedtls_sha384_info = {
sha384_process_wrap, sha384_process_wrap,
}; };
static void sha512_starts_wrap( void *ctx ) static int sha512_starts_wrap( void *ctx )
{ {
mbedtls_sha512_starts( (mbedtls_sha512_context *) ctx, 0 ); return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
} }
static void sha512_wrap( const unsigned char *input, size_t ilen, static int sha512_wrap( const unsigned char *input, size_t ilen,
unsigned char *output ) unsigned char *output )
{ {
mbedtls_sha512( input, ilen, output, 0 ); return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
} }
const mbedtls_md_info_t mbedtls_sha512_info = { const mbedtls_md_info_t mbedtls_sha512_info = {

View file

@ -184,9 +184,9 @@ static int verify_header( memory_header *hdr )
static int verify_chain() static int verify_chain()
{ {
memory_header *prv = heap.first, *cur = heap.first->next; memory_header *prv = heap.first, *cur;
if( verify_header( heap.first ) != 0 ) if( prv == NULL || verify_header( prv ) != 0 )
{ {
#if defined(MBEDTLS_MEMORY_DEBUG) #if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: verification of first header " mbedtls_fprintf( stderr, "FATAL: verification of first header "
@ -204,6 +204,8 @@ static int verify_chain()
return( 1 ); return( 1 );
} }
cur = heap.first->next;
while( cur != NULL ) while( cur != NULL )
{ {
if( verify_header( cur ) != 0 ) if( verify_header( cur ) != 0 )
@ -247,7 +249,9 @@ static void *buffer_alloc_calloc( size_t n, size_t size )
original_len = len = n * size; original_len = len = n * size;
if( n != 0 && len / n != size ) if( n == 0 || size == 0 || len / n != size )
return( NULL );
else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE )
return( NULL ); return( NULL );
if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
@ -388,7 +392,7 @@ static void buffer_alloc_free( void *ptr )
if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
return; return;
if( p < heap.buf || p > heap.buf + heap.len ) if( p < heap.buf || p >= heap.buf + heap.len )
{ {
#if defined(MBEDTLS_MEMORY_DEBUG) #if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed " mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
@ -520,7 +524,9 @@ void mbedtls_memory_buffer_alloc_status()
heap.alloc_count, heap.free_count ); heap.alloc_count, heap.free_count );
if( heap.first->next == NULL ) if( heap.first->next == NULL )
{
mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
}
else else
{ {
mbedtls_fprintf( stderr, "Memory currently allocated:\n" ); mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
@ -572,8 +578,7 @@ static void buffer_alloc_free_mutexed( void *ptr )
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
{ {
memset( &heap, 0, sizeof(buffer_alloc_ctx) ); memset( &heap, 0, sizeof( buffer_alloc_ctx ) );
memset( buf, 0, len );
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &heap.mutex ); mbedtls_mutex_init( &heap.mutex );
@ -583,20 +588,24 @@ void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free ); mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
#endif #endif
if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE )
return;
else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
{ {
/* Adjust len first since buf is used in the computation */ /* Adjust len first since buf is used in the computation */
len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
- (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
- (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
} }
memset( buf, 0, len );
heap.buf = buf; heap.buf = buf;
heap.len = len; heap.len = len;
heap.first = (memory_header *) buf; heap.first = (memory_header *)buf;
heap.first->size = len - sizeof(memory_header); heap.first->size = len - sizeof( memory_header );
heap.first->magic1 = MAGIC1; heap.first->magic1 = MAGIC1;
heap.first->magic2 = MAGIC2; heap.first->magic2 = MAGIC2;
heap.first_free = heap.first; heap.first_free = heap.first;

View file

@ -47,11 +47,12 @@
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
!defined(EFI32) !defined(EFI32)
#ifdef _WIN32_WINNT #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
#undef _WIN32_WINNT #undef _WIN32_WINNT
#endif
/* Enables getaddrinfo() & Co */ /* Enables getaddrinfo() & Co */
#define _WIN32_WINNT 0x0501 #define _WIN32_WINNT 0x0501
#endif
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <winsock2.h> #include <winsock2.h>
@ -65,8 +66,8 @@
#endif #endif
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0) #define read(fd,buf,len) recv( fd, (char*)( buf ), (int)( len ), 0 )
#define write(fd,buf,len) send(fd,(char*)buf,(int) len,0) #define write(fd,buf,len) send( fd, (char*)( buf ), (int)( len ), 0 )
#define close(fd) closesocket(fd) #define close(fd) closesocket(fd)
static int wsa_init_done = 0; static int wsa_init_done = 0;
@ -87,7 +88,7 @@ static int wsa_init_done = 0;
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
/* Some MS functions want int and MSVC warns if we pass size_t, /* Some MS functions want int and MSVC warns if we pass size_t,
* but the standard fucntions use socklen_t, so cast only for MSVC */ * but the standard functions use socklen_t, so cast only for MSVC */
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define MSVC_INT_CAST (int) #define MSVC_INT_CAST (int)
#else #else
@ -272,13 +273,18 @@ static int net_would_block( const mbedtls_net_context *ctx )
*/ */
static int net_would_block( const mbedtls_net_context *ctx ) static int net_would_block( const mbedtls_net_context *ctx )
{ {
int err = errno;
/* /*
* Never return 'WOULD BLOCK' on a non-blocking socket * Never return 'WOULD BLOCK' on a non-blocking socket
*/ */
if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK ) if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
{
errno = err;
return( 0 ); return( 0 );
}
switch( errno ) switch( errno = err )
{ {
#if defined EAGAIN #if defined EAGAIN
case EAGAIN: case EAGAIN:

View file

@ -627,6 +627,51 @@ static const oid_md_alg_t oid_md_alg[] =
FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg) FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg)
FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg) FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg)
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg) FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg)
/*
* For HMAC digestAlgorithm
*/
typedef struct {
mbedtls_oid_descriptor_t descriptor;
mbedtls_md_type_t md_hmac;
} oid_md_hmac_t;
static const oid_md_hmac_t oid_md_hmac[] =
{
#if defined(MBEDTLS_SHA1_C)
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" },
MBEDTLS_MD_SHA1,
},
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" },
MBEDTLS_MD_SHA224,
},
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" },
MBEDTLS_MD_SHA256,
},
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" },
MBEDTLS_MD_SHA384,
},
{
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" },
MBEDTLS_MD_SHA512,
},
#endif /* MBEDTLS_SHA512_C */
{
{ NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE,
},
};
FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac)
FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac)
#endif /* MBEDTLS_MD_C */ #endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PKCS12_C) #if defined(MBEDTLS_PKCS12_C)

View file

@ -84,31 +84,33 @@ static int pem_get_iv( const unsigned char *s, unsigned char *iv,
return( 0 ); return( 0 );
} }
static void pem_pbkdf1( unsigned char *key, size_t keylen, static int pem_pbkdf1( unsigned char *key, size_t keylen,
unsigned char *iv, unsigned char *iv,
const unsigned char *pwd, size_t pwdlen ) const unsigned char *pwd, size_t pwdlen )
{ {
mbedtls_md5_context md5_ctx; mbedtls_md5_context md5_ctx;
unsigned char md5sum[16]; unsigned char md5sum[16];
size_t use_len; size_t use_len;
int ret;
mbedtls_md5_init( &md5_ctx ); mbedtls_md5_init( &md5_ctx );
/* /*
* key[ 0..15] = MD5(pwd || IV) * key[ 0..15] = MD5(pwd || IV)
*/ */
mbedtls_md5_starts( &md5_ctx ); if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
mbedtls_md5_update( &md5_ctx, pwd, pwdlen ); goto exit;
mbedtls_md5_update( &md5_ctx, iv, 8 ); if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
mbedtls_md5_finish( &md5_ctx, md5sum ); goto exit;
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
goto exit;
if( keylen <= 16 ) if( keylen <= 16 )
{ {
memcpy( key, md5sum, keylen ); memcpy( key, md5sum, keylen );
goto exit;
mbedtls_md5_free( &md5_ctx );
mbedtls_zeroize( md5sum, 16 );
return;
} }
memcpy( key, md5sum, 16 ); memcpy( key, md5sum, 16 );
@ -116,11 +118,16 @@ static void pem_pbkdf1( unsigned char *key, size_t keylen,
/* /*
* key[16..23] = MD5(key[ 0..15] || pwd || IV]) * key[16..23] = MD5(key[ 0..15] || pwd || IV])
*/ */
mbedtls_md5_starts( &md5_ctx ); if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
mbedtls_md5_update( &md5_ctx, md5sum, 16 ); goto exit;
mbedtls_md5_update( &md5_ctx, pwd, pwdlen ); if( ( ret = mbedtls_md5_update_ret( &md5_ctx, md5sum, 16 ) ) != 0 )
mbedtls_md5_update( &md5_ctx, iv, 8 ); goto exit;
mbedtls_md5_finish( &md5_ctx, md5sum ); if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 )
goto exit;
if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
goto exit;
use_len = 16; use_len = 16;
if( keylen < 32 ) if( keylen < 32 )
@ -128,53 +135,68 @@ static void pem_pbkdf1( unsigned char *key, size_t keylen,
memcpy( key + 16, md5sum, use_len ); memcpy( key + 16, md5sum, use_len );
exit:
mbedtls_md5_free( &md5_ctx ); mbedtls_md5_free( &md5_ctx );
mbedtls_zeroize( md5sum, 16 ); mbedtls_zeroize( md5sum, 16 );
return( ret );
} }
#if defined(MBEDTLS_DES_C) #if defined(MBEDTLS_DES_C)
/* /*
* Decrypt with DES-CBC, using PBKDF1 for key derivation * Decrypt with DES-CBC, using PBKDF1 for key derivation
*/ */
static void pem_des_decrypt( unsigned char des_iv[8], static int pem_des_decrypt( unsigned char des_iv[8],
unsigned char *buf, size_t buflen, unsigned char *buf, size_t buflen,
const unsigned char *pwd, size_t pwdlen ) const unsigned char *pwd, size_t pwdlen )
{ {
mbedtls_des_context des_ctx; mbedtls_des_context des_ctx;
unsigned char des_key[8]; unsigned char des_key[8];
int ret;
mbedtls_des_init( &des_ctx ); mbedtls_des_init( &des_ctx );
pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ); if( ( ret = pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ) ) != 0 )
goto exit;
mbedtls_des_setkey_dec( &des_ctx, des_key ); if( ( ret = mbedtls_des_setkey_dec( &des_ctx, des_key ) ) != 0 )
mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen, goto exit;
ret = mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen,
des_iv, buf, buf ); des_iv, buf, buf );
exit:
mbedtls_des_free( &des_ctx ); mbedtls_des_free( &des_ctx );
mbedtls_zeroize( des_key, 8 ); mbedtls_zeroize( des_key, 8 );
return( ret );
} }
/* /*
* Decrypt with 3DES-CBC, using PBKDF1 for key derivation * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
*/ */
static void pem_des3_decrypt( unsigned char des3_iv[8], static int pem_des3_decrypt( unsigned char des3_iv[8],
unsigned char *buf, size_t buflen, unsigned char *buf, size_t buflen,
const unsigned char *pwd, size_t pwdlen ) const unsigned char *pwd, size_t pwdlen )
{ {
mbedtls_des3_context des3_ctx; mbedtls_des3_context des3_ctx;
unsigned char des3_key[24]; unsigned char des3_key[24];
int ret;
mbedtls_des3_init( &des3_ctx ); mbedtls_des3_init( &des3_ctx );
pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ); if( ( ret = pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ) ) != 0 )
goto exit;
mbedtls_des3_set3key_dec( &des3_ctx, des3_key ); if( ( ret = mbedtls_des3_set3key_dec( &des3_ctx, des3_key ) ) != 0 )
mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen, goto exit;
ret = mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen,
des3_iv, buf, buf ); des3_iv, buf, buf );
exit:
mbedtls_des3_free( &des3_ctx ); mbedtls_des3_free( &des3_ctx );
mbedtls_zeroize( des3_key, 24 ); mbedtls_zeroize( des3_key, 24 );
return( ret );
} }
#endif /* MBEDTLS_DES_C */ #endif /* MBEDTLS_DES_C */
@ -182,23 +204,29 @@ static void pem_des3_decrypt( unsigned char des3_iv[8],
/* /*
* Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation
*/ */
static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
unsigned char *buf, size_t buflen, unsigned char *buf, size_t buflen,
const unsigned char *pwd, size_t pwdlen ) const unsigned char *pwd, size_t pwdlen )
{ {
mbedtls_aes_context aes_ctx; mbedtls_aes_context aes_ctx;
unsigned char aes_key[32]; unsigned char aes_key[32];
int ret;
mbedtls_aes_init( &aes_ctx ); mbedtls_aes_init( &aes_ctx );
pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ); if( ( ret = pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ) ) != 0 )
goto exit;
mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ); if( ( ret = mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ) ) != 0 )
mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen, goto exit;
ret = mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen,
aes_iv, buf, buf ); aes_iv, buf, buf );
exit:
mbedtls_aes_free( &aes_ctx ); mbedtls_aes_free( &aes_ctx );
mbedtls_zeroize( aes_key, keylen ); mbedtls_zeroize( aes_key, keylen );
return( ret );
} }
#endif /* MBEDTLS_AES_C */ #endif /* MBEDTLS_AES_C */
@ -333,6 +361,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 ) if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
{ {
mbedtls_zeroize( buf, len );
mbedtls_free( buf ); mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
} }
@ -343,26 +372,35 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
if( pwd == NULL ) if( pwd == NULL )
{ {
mbedtls_zeroize( buf, len );
mbedtls_free( buf ); mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ); return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED );
} }
ret = 0;
#if defined(MBEDTLS_DES_C) #if defined(MBEDTLS_DES_C)
if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC ) if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC )
pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen ); ret = pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
else if( enc_alg == MBEDTLS_CIPHER_DES_CBC ) else if( enc_alg == MBEDTLS_CIPHER_DES_CBC )
pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen ); ret = pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
#endif /* MBEDTLS_DES_C */ #endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_AES_C)
if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC ) if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC )
pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen ); ret = pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC ) else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC )
pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen ); ret = pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC ) else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC )
pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen ); ret = pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
#endif /* MBEDTLS_AES_C */ #endif /* MBEDTLS_AES_C */
if( ret != 0 )
{
mbedtls_free( buf );
return( ret );
}
/* /*
* The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
* length bytes (allow 4 to be sure) in all known use cases. * length bytes (allow 4 to be sure) in all known use cases.
@ -371,10 +409,12 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
*/ */
if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
{ {
mbedtls_zeroize( buf, len );
mbedtls_free( buf ); mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ); return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH );
} }
#else #else
mbedtls_zeroize( buf, len );
mbedtls_free( buf ); mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
@ -389,6 +429,8 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
void mbedtls_pem_free( mbedtls_pem_context *ctx ) void mbedtls_pem_free( mbedtls_pem_context *ctx )
{ {
if( ctx->buf != NULL )
mbedtls_zeroize( ctx->buf, ctx->buflen );
mbedtls_free( ctx->buf ); mbedtls_free( ctx->buf );
mbedtls_free( ctx->info ); mbedtls_free( ctx->info );
@ -402,7 +444,7 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
unsigned char *buf, size_t buf_len, size_t *olen ) unsigned char *buf, size_t buf_len, size_t *olen )
{ {
int ret; int ret;
unsigned char *encode_buf, *c, *p = buf; unsigned char *encode_buf = NULL, *c, *p = buf;
size_t len = 0, use_len, add_len = 0; size_t len = 0, use_len, add_len = 0;
mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len ); mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len );
@ -414,7 +456,8 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
} }
if( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) if( use_len != 0 &&
( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) )
return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data, if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data,

View file

@ -31,8 +31,6 @@
#include "mbedtls/pk.h" #include "mbedtls/pk.h"
#include "mbedtls/pk_internal.h" #include "mbedtls/pk_internal.h"
#include "mbedtls/bignum.h"
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
#endif #endif
@ -44,6 +42,7 @@
#endif #endif
#include <limits.h> #include <limits.h>
#include <stdint.h>
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
@ -215,10 +214,10 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
int ret; int ret;
const mbedtls_pk_rsassa_pss_options *pss_opts; const mbedtls_pk_rsassa_pss_options *pss_opts;
#if defined(MBEDTLS_HAVE_INT64) #if SIZE_MAX > UINT_MAX
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* MBEDTLS_HAVE_INT64 */ #endif /* SIZE_MAX > UINT_MAX */
if( options == NULL ) if( options == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );

View file

@ -32,7 +32,6 @@
/* Even if RSA not activated, for the sake of RSA-alt */ /* Even if RSA not activated, for the sake of RSA-alt */
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
#include "mbedtls/bignum.h"
#include <string.h> #include <string.h>
@ -53,6 +52,7 @@
#endif #endif
#include <limits.h> #include <limits.h>
#include <stdint.h>
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
@ -70,7 +70,8 @@ static int rsa_can_do( mbedtls_pk_type_t type )
static size_t rsa_get_bitlen( const void *ctx ) static size_t rsa_get_bitlen( const void *ctx )
{ {
return( 8 * ((const mbedtls_rsa_context *) ctx)->len ); const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
return( 8 * mbedtls_rsa_get_len( rsa ) );
} }
static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
@ -78,21 +79,28 @@ static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *sig, size_t sig_len ) const unsigned char *sig, size_t sig_len )
{ {
int ret; int ret;
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
size_t rsa_len = mbedtls_rsa_get_len( rsa );
#if defined(MBEDTLS_HAVE_INT64) #if SIZE_MAX > UINT_MAX
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* MBEDTLS_HAVE_INT64 */ #endif /* SIZE_MAX > UINT_MAX */
if( sig_len < ((mbedtls_rsa_context *) ctx)->len ) if( sig_len < rsa_len )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL, if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
MBEDTLS_RSA_PUBLIC, md_alg, MBEDTLS_RSA_PUBLIC, md_alg,
(unsigned int) hash_len, hash, sig ) ) != 0 ) (unsigned int) hash_len, hash, sig ) ) != 0 )
return( ret ); return( ret );
if( sig_len > ((mbedtls_rsa_context *) ctx)->len ) /* The buffer contains a valid signature followed by extra data.
* We have a special error code for that so that so that callers can
* use mbedtls_pk_verify() to check "Does the buffer start with a
* valid signature?" and not just "Does the buffer contain a valid
* signature?". */
if( sig_len > rsa_len )
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
return( 0 ); return( 0 );
@ -103,14 +111,16 @@ static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
unsigned char *sig, size_t *sig_len, unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{ {
#if defined(MBEDTLS_HAVE_INT64) mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
#if SIZE_MAX > UINT_MAX
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* MBEDTLS_HAVE_INT64 */ #endif /* SIZE_MAX > UINT_MAX */
*sig_len = ((mbedtls_rsa_context *) ctx)->len; *sig_len = mbedtls_rsa_get_len( rsa );
return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
md_alg, (unsigned int) hash_len, hash, sig ) ); md_alg, (unsigned int) hash_len, hash, sig ) );
} }
@ -119,10 +129,12 @@ static int rsa_decrypt_wrap( void *ctx,
unsigned char *output, size_t *olen, size_t osize, unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{ {
if( ilen != ((mbedtls_rsa_context *) ctx)->len ) mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
if( ilen != mbedtls_rsa_get_len( rsa ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng, return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
} }
@ -131,13 +143,14 @@ static int rsa_encrypt_wrap( void *ctx,
unsigned char *output, size_t *olen, size_t osize, unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{ {
*olen = ((mbedtls_rsa_context *) ctx)->len; mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
*olen = mbedtls_rsa_get_len( rsa );
if( *olen > osize ) if( *olen > osize )
return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx, return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) ); ilen, input, output ) );
} }
static int rsa_check_pair_wrap( const void *pub, const void *prv ) static int rsa_check_pair_wrap( const void *pub, const void *prv )
@ -417,10 +430,10 @@ static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
{ {
mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
#if defined(MBEDTLS_HAVE_INT64) #if SIZE_MAX > UINT_MAX
if( UINT_MAX < hash_len ) if( UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* MBEDTLS_HAVE_INT64 */ #endif /* SIZE_MAX > UINT_MAX */
*sig_len = rsa_alt->key_len_func( rsa_alt->key ); *sig_len = rsa_alt->key_len_func( rsa_alt->key );

View file

@ -40,9 +40,12 @@
#if defined(MBEDTLS_PKCS5_C) #if defined(MBEDTLS_PKCS5_C)
#include "mbedtls/pkcs5.h" #include "mbedtls/pkcs5.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "mbedtls/asn1.h" #include "mbedtls/asn1.h"
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#include "mbedtls/oid.h" #include "mbedtls/oid.h"
#endif /* MBEDTLS_ASN1_PARSE_C */
#include <string.h> #include <string.h>
@ -53,6 +56,22 @@
#define mbedtls_printf printf #define mbedtls_printf printf
#endif #endif
#if !defined(MBEDTLS_ASN1_PARSE_C)
int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t datalen,
unsigned char *output )
{
((void) pbe_params);
((void) mode);
((void) pwd);
((void) pwdlen);
((void) data);
((void) datalen);
((void) output);
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
}
#else
static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
mbedtls_asn1_buf *salt, int *iterations, mbedtls_asn1_buf *salt, int *iterations,
int *keylen, mbedtls_md_type_t *md_type ) int *keylen, mbedtls_md_type_t *md_type )
@ -98,11 +117,9 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 ) if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 )
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
*md_type = MBEDTLS_MD_SHA1;
if( p != end ) if( p != end )
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
@ -215,6 +232,7 @@ exit:
return( ret ); return( ret );
} }
#endif /* MBEDTLS_ASN1_PARSE_C */
int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password, int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
size_t plen, const unsigned char *salt, size_t slen, size_t plen, const unsigned char *salt, size_t slen,
@ -233,8 +251,10 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
memset( counter, 0, 4 ); memset( counter, 0, 4 );
counter[3] = 1; counter[3] = 1;
#if UINT_MAX > 0xFFFFFFFF
if( iteration_count > 0xFFFFFFFF ) if( iteration_count > 0xFFFFFFFF )
return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
#endif
while( key_length ) while( key_length )
{ {

View file

@ -62,12 +62,15 @@
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#if defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_FS_IO) || \
defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0; volatile unsigned char *p = v; while( n-- ) *p++ = 0;
} }
#endif
#if defined(MBEDTLS_FS_IO)
/* /*
* Load all data from a file into a given buffer. * Load all data from a file into a given buffer.
* *
@ -103,7 +106,10 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
if( fread( *buf, 1, *n, f ) != *n ) if( fread( *buf, 1, *n, f ) != *n )
{ {
fclose( f ); fclose( f );
mbedtls_zeroize( *buf, *n );
mbedtls_free( *buf ); mbedtls_free( *buf );
return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
} }
@ -177,6 +183,10 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
{ {
int ret; int ret;
if ( end - *p < 1 )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
MBEDTLS_ERR_ASN1_OUT_OF_DATA );
/* Tag may be either OID or SEQUENCE */ /* Tag may be either OID or SEQUENCE */
params->tag = **p; params->tag = **p;
if( params->tag != MBEDTLS_ASN1_OID if( params->tag != MBEDTLS_ASN1_OID
@ -522,19 +532,36 @@ static int pk_get_rsapubkey( unsigned char **p,
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
if( ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->N ) ) != 0 || /* Import N */
( ret = mbedtls_asn1_get_mpi( p, end, &rsa->E ) ) != 0 ) if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
NULL, 0, NULL, 0 ) ) != 0 )
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
*p += len;
/* Import E */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, *p, len ) ) != 0 )
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
*p += len;
if( mbedtls_rsa_complete( rsa ) != 0 ||
mbedtls_rsa_check_pubkey( rsa ) != 0 )
{
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
}
if( *p != end ) if( *p != end )
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
if( ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 )
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
rsa->len = mbedtls_mpi_size( &rsa->N );
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_RSA_C */ #endif /* MBEDTLS_RSA_C */
@ -645,10 +672,13 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
const unsigned char *key, const unsigned char *key,
size_t keylen ) size_t keylen )
{ {
int ret; int ret, version;
size_t len; size_t len;
unsigned char *p, *end; unsigned char *p, *end;
mbedtls_mpi T;
mbedtls_mpi_init( &T );
p = (unsigned char *) key; p = (unsigned char *) key;
end = p + keylen; end = p + keylen;
@ -676,45 +706,88 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
end = p + len; end = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
{ {
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
} }
if( rsa->ver != 0 ) if( version != 0 )
{ {
return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
} }
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->N ) ) != 0 || /* Import N */
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->E ) ) != 0 || if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->D ) ) != 0 || MBEDTLS_ASN1_INTEGER ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->P ) ) != 0 || ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0,
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 || NULL, 0, NULL, 0 ) ) != 0 )
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 || goto cleanup;
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 || p += len;
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
{
mbedtls_rsa_free( rsa );
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
}
rsa->len = mbedtls_mpi_size( &rsa->N ); /* Import E */
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, p, len ) ) != 0 )
goto cleanup;
p += len;
/* Import D */
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
p, len, NULL, 0 ) ) != 0 )
goto cleanup;
p += len;
/* Import P */
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0,
NULL, 0, NULL, 0 ) ) != 0 )
goto cleanup;
p += len;
/* Import Q */
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len,
NULL, 0, NULL, 0 ) ) != 0 )
goto cleanup;
p += len;
/* Complete the RSA private key */
if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
goto cleanup;
/* Check optional parameters */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 )
goto cleanup;
if( p != end ) if( p != end )
{ {
mbedtls_rsa_free( rsa ); ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
} }
if( ( ret = mbedtls_rsa_check_privkey( rsa ) ) != 0 ) cleanup:
mbedtls_mpi_free( &T );
if( ret != 0 )
{ {
/* Wrap error code if it's coming from a lower level */
if( ( ret & 0xff80 ) == 0 )
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
else
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
mbedtls_rsa_free( rsa ); mbedtls_rsa_free( rsa );
return( ret );
} }
return( 0 ); return( ret );
} }
#endif /* MBEDTLS_RSA_C */ #endif /* MBEDTLS_RSA_C */
@ -790,7 +863,10 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
mbedtls_ecp_keypair_free( eck ); mbedtls_ecp_keypair_free( eck );
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
} }
}
if( p != end )
{
/* /*
* Is 'publickey' present? If not, or if we can't read it (eg because it * Is 'publickey' present? If not, or if we can't read it (eg because it
* is compressed), create it from the private key. * is compressed), create it from the private key.
@ -846,6 +922,16 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
/* /*
* Parse an unencrypted PKCS#8 encoded private key * Parse an unencrypted PKCS#8 encoded private key
*
* Notes:
*
* - This function does not own the key buffer. It is the
* responsibility of the caller to take care of zeroizing
* and freeing it after use.
*
* - The function is responsible for freeing the provided
* PK context on failure.
*
*/ */
static int pk_parse_key_pkcs8_unencrypted_der( static int pk_parse_key_pkcs8_unencrypted_der(
mbedtls_pk_context *pk, mbedtls_pk_context *pk,
@ -861,7 +947,7 @@ static int pk_parse_key_pkcs8_unencrypted_der(
const mbedtls_pk_info_t *pk_info; const mbedtls_pk_info_t *pk_info;
/* /*
* This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208) * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
* *
* PrivateKeyInfo ::= SEQUENCE { * PrivateKeyInfo ::= SEQUENCE {
* version Version, * version Version,
@ -934,16 +1020,22 @@ static int pk_parse_key_pkcs8_unencrypted_der(
/* /*
* Parse an encrypted PKCS#8 encoded private key * Parse an encrypted PKCS#8 encoded private key
*
* To save space, the decryption happens in-place on the given key buffer.
* Also, while this function may modify the keybuffer, it doesn't own it,
* and instead it is the responsibility of the caller to zeroize and properly
* free it after use.
*
*/ */
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
static int pk_parse_key_pkcs8_encrypted_der( static int pk_parse_key_pkcs8_encrypted_der(
mbedtls_pk_context *pk, mbedtls_pk_context *pk,
const unsigned char *key, size_t keylen, unsigned char *key, size_t keylen,
const unsigned char *pwd, size_t pwdlen ) const unsigned char *pwd, size_t pwdlen )
{ {
int ret, decrypted = 0; int ret, decrypted = 0;
size_t len; size_t len;
unsigned char buf[2048]; unsigned char *buf;
unsigned char *p, *end; unsigned char *p, *end;
mbedtls_asn1_buf pbe_alg_oid, pbe_params; mbedtls_asn1_buf pbe_alg_oid, pbe_params;
#if defined(MBEDTLS_PKCS12_C) #if defined(MBEDTLS_PKCS12_C)
@ -951,16 +1043,14 @@ static int pk_parse_key_pkcs8_encrypted_der(
mbedtls_md_type_t md_alg; mbedtls_md_type_t md_alg;
#endif #endif
memset( buf, 0, sizeof( buf ) ); p = key;
p = (unsigned char *) key;
end = p + keylen; end = p + keylen;
if( pwdlen == 0 ) if( pwdlen == 0 )
return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
/* /*
* This function parses the EncryptedPrivatKeyInfo object (PKCS#8) * This function parses the EncryptedPrivateKeyInfo object (PKCS#8)
* *
* EncryptedPrivateKeyInfo ::= SEQUENCE { * EncryptedPrivateKeyInfo ::= SEQUENCE {
* encryptionAlgorithm EncryptionAlgorithmIdentifier, * encryptionAlgorithm EncryptionAlgorithmIdentifier,
@ -972,6 +1062,7 @@ static int pk_parse_key_pkcs8_encrypted_der(
* EncryptedData ::= OCTET STRING * EncryptedData ::= OCTET STRING
* *
* The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
*
*/ */
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
@ -987,11 +1078,10 @@ static int pk_parse_key_pkcs8_encrypted_der(
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
if( len > sizeof( buf ) ) buf = p;
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
/* /*
* Decrypt EncryptedData with appropriate PDE * Decrypt EncryptedData with appropriate PBE
*/ */
#if defined(MBEDTLS_PKCS12_C) #if defined(MBEDTLS_PKCS12_C)
if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 ) if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
@ -1083,9 +1173,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
if( ret == 0 ) if( ret == 0 )
{ {
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
pem.buf, pem.buflen ) ) != 0 ) pem.buf, pem.buflen ) ) != 0 )
@ -1115,8 +1203,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
key, pwd, pwdlen, &len ); key, pwd, pwdlen, &len );
if( ret == 0 ) if( ret == 0 )
{ {
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL ) pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
@ -1183,7 +1270,6 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
return( ret ); return( ret );
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
#else #else
((void) ret);
((void) pwd); ((void) pwd);
((void) pwdlen); ((void) pwdlen);
#endif /* MBEDTLS_PEM_PARSE_C */ #endif /* MBEDTLS_PEM_PARSE_C */
@ -1196,12 +1282,27 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
* error * error
*/ */
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
pwd, pwdlen ) ) == 0 )
{ {
return( 0 ); unsigned char *key_copy;
if( keylen == 0 )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
memcpy( key_copy, key, keylen );
ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
pwd, pwdlen );
mbedtls_zeroize( key_copy, keylen );
mbedtls_free( key_copy );
} }
if( ret == 0 )
return( 0 );
mbedtls_pk_free( pk ); mbedtls_pk_free( pk );
if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH ) if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH )
@ -1216,29 +1317,35 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
mbedtls_pk_free( pk ); mbedtls_pk_free( pk );
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) ) == 0 ) ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
key, keylen ) ) != 0 )
{
mbedtls_pk_free( pk );
}
else
{ {
return( 0 ); return( 0 );
} }
mbedtls_pk_free( pk );
#endif /* MBEDTLS_RSA_C */ #endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), key, keylen ) ) == 0 ) ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
key, keylen ) ) != 0 )
{
mbedtls_pk_free( pk );
}
else
{ {
return( 0 ); return( 0 );
} }
mbedtls_pk_free( pk );
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );

View file

@ -68,9 +68,27 @@ static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
{ {
int ret; int ret;
size_t len = 0; size_t len = 0;
mbedtls_mpi T;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->E ) ); mbedtls_mpi_init( &T );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->N ) );
/* Export E */
if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
goto end_of_export;
len += ret;
/* Export N */
if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
goto end_of_export;
len += ret;
end_of_export:
mbedtls_mpi_free( &T );
if( ret < 0 )
return( ret );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
@ -207,20 +225,78 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
{ {
mbedtls_mpi T; /* Temporary holding the exported parameters */
mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) ); /*
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) ); * Export the parameters one after another to avoid simultaneous copies.
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) ); */
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
mbedtls_mpi_init( &T );
/* Export QP */
if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
goto end_of_export;
len += ret;
/* Export DQ */
if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
goto end_of_export;
len += ret;
/* Export DP */
if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
goto end_of_export;
len += ret;
/* Export Q */
if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
&T, NULL, NULL ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
goto end_of_export;
len += ret;
/* Export P */
if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T,
NULL, NULL, NULL ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
goto end_of_export;
len += ret;
/* Export D */
if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
NULL, &T, NULL ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
goto end_of_export;
len += ret;
/* Export E */
if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
NULL, NULL, &T ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
goto end_of_export;
len += ret;
/* Export N */
if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL,
NULL, NULL, NULL ) ) != 0 ||
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
goto end_of_export;
len += ret;
end_of_export:
mbedtls_mpi_free( &T );
if( ret < 0 )
return( ret );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c,
buf, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE ) ); MBEDTLS_ASN1_SEQUENCE ) );
} }
else else

View file

@ -31,6 +31,14 @@
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#if defined(MBEDTLS_ENTROPY_NV_SEED) && \
!defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
#endif
#if defined(MBEDTLS_PLATFORM_MEMORY) #if defined(MBEDTLS_PLATFORM_MEMORY)
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) #if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
static void *platform_calloc_uninit( size_t n, size_t size ) static void *platform_calloc_uninit( size_t n, size_t size )
@ -76,7 +84,7 @@ int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
return( -1 ); return( -1 );
va_start( argp, fmt ); va_start( argp, fmt );
#if defined(_TRUNCATE) #if defined(_TRUNCATE) && !defined(__MINGW32__)
ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp ); ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
#else #else
ret = _vsnprintf( s, n, fmt, argp ); ret = _vsnprintf( s, n, fmt, argp );
@ -230,12 +238,13 @@ int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len )
size_t n; size_t n;
if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
return -1; return( -1 );
if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
{ {
fclose( file ); fclose( file );
return -1; mbedtls_zeroize( buf, buf_len );
return( -1 );
} }
fclose( file ); fclose( file );

View file

@ -48,6 +48,8 @@
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_RIPEMD160_ALT)
/* /*
* 32-bit integer manipulation macros (little endian) * 32-bit integer manipulation macros (little endian)
*/ */
@ -98,7 +100,7 @@ void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
/* /*
* RIPEMD-160 context setup * RIPEMD-160 context setup
*/ */
void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx ) int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
{ {
ctx->total[0] = 0; ctx->total[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
@ -108,13 +110,23 @@ void mbedtls_ripemd160_starts( mbedtls_ripemd160_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_DEPRECATED_REMOVED)
void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
{
mbedtls_ripemd160_starts_ret( ctx );
}
#endif
#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
/* /*
* Process one block * Process one block
*/ */
void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] ) int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
const unsigned char data[64] )
{ {
uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
@ -289,20 +301,32 @@ void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned c
ctx->state[3] = ctx->state[4] + A + Bp; ctx->state[3] = ctx->state[4] + A + Bp;
ctx->state[4] = ctx->state[0] + B + Cp; ctx->state[4] = ctx->state[0] + B + Cp;
ctx->state[0] = C; ctx->state[0] = C;
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_ripemd160_process( ctx, data );
}
#endif
#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
/* /*
* RIPEMD-160 process buffer * RIPEMD-160 process buffer
*/ */
void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx, int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
const unsigned char *input, 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;
@ -316,7 +340,10 @@ void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
if( left && ilen >= fill ) if( left && ilen >= fill )
{ {
memcpy( (void *) (ctx->buffer + left), input, fill ); memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_ripemd160_process( ctx, ctx->buffer );
if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
input += fill; input += fill;
ilen -= fill; ilen -= fill;
left = 0; left = 0;
@ -324,7 +351,9 @@ void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
while( ilen >= 64 ) while( ilen >= 64 )
{ {
mbedtls_ripemd160_process( ctx, input ); if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
return( ret );
input += 64; input += 64;
ilen -= 64; ilen -= 64;
} }
@ -333,8 +362,19 @@ void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
{ {
memcpy( (void *) (ctx->buffer + left), input, ilen ); memcpy( (void *) (ctx->buffer + left), input, ilen );
} }
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_ripemd160_update_ret( ctx, input, ilen );
}
#endif
static const unsigned char ripemd160_padding[64] = static const unsigned char ripemd160_padding[64] =
{ {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -346,8 +386,10 @@ static const unsigned char ripemd160_padding[64] =
/* /*
* RIPEMD-160 final digest * RIPEMD-160 final digest
*/ */
void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char output[20] ) int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_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];
@ -362,49 +404,91 @@ void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char out
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_ripemd160_update( ctx, ripemd160_padding, padn ); ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
mbedtls_ripemd160_update( ctx, msglen, 8 ); if( ret != 0 )
return( ret );
ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
if( ret != 0 )
return( ret );
PUT_UINT32_LE( ctx->state[0], output, 0 ); PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 ); PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 ); PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 ); PUT_UINT32_LE( ctx->state[3], output, 12 );
PUT_UINT32_LE( ctx->state[4], output, 16 ); PUT_UINT32_LE( ctx->state[4], output, 16 );
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
unsigned char output[20] )
{
mbedtls_ripemd160_finish_ret( ctx, output );
}
#endif
#endif /* ! MBEDTLS_RIPEMD160_ALT */
/* /*
* output = RIPEMD-160( input buffer ) * output = RIPEMD-160( input buffer )
*/ */
void mbedtls_ripemd160( const unsigned char *input, size_t ilen, int mbedtls_ripemd160_ret( const unsigned char *input,
size_t ilen,
unsigned char output[20] ) unsigned char output[20] )
{ {
int ret;
mbedtls_ripemd160_context ctx; mbedtls_ripemd160_context ctx;
mbedtls_ripemd160_init( &ctx ); mbedtls_ripemd160_init( &ctx );
mbedtls_ripemd160_starts( &ctx );
mbedtls_ripemd160_update( &ctx, input, ilen ); if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
mbedtls_ripemd160_finish( &ctx, output ); goto exit;
if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
goto exit;
if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
goto exit;
exit:
mbedtls_ripemd160_free( &ctx ); mbedtls_ripemd160_free( &ctx );
return( ret );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_ripemd160( const unsigned char *input,
size_t ilen,
unsigned char output[20] )
{
mbedtls_ripemd160_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* Test vectors from the RIPEMD-160 paper and * Test vectors from the RIPEMD-160 paper and
* http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
*/ */
#define TESTS 8 #define TESTS 8
#define KEYS 2 static const unsigned char ripemd160_test_str[TESTS][81] =
static const char *ripemd160_test_input[TESTS] =
{ {
"", { "" },
"a", { "a" },
"abc", { "abc" },
"message digest", { "message digest" },
"abcdefghijklmnopqrstuvwxyz", { "abcdefghijklmnopqrstuvwxyz" },
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
"1234567890123456789012345678901234567890" { "12345678901234567890123456789012345678901234567890123456789012"
"1234567890123456789012345678901234567890", "345678901234567890" },
};
static const size_t ripemd160_test_strlen[TESTS] =
{
0, 1, 3, 14, 26, 56, 62, 80
}; };
static const unsigned char ripemd160_test_md[TESTS][20] = static const unsigned char ripemd160_test_md[TESTS][20] =
@ -432,7 +516,7 @@ static const unsigned char ripemd160_test_md[TESTS][20] =
*/ */
int mbedtls_ripemd160_self_test( int verbose ) int mbedtls_ripemd160_self_test( int verbose )
{ {
int i; int i, ret = 0;
unsigned char output[20]; unsigned char output[20];
memset( output, 0, sizeof output ); memset( output, 0, sizeof output );
@ -442,16 +526,15 @@ int mbedtls_ripemd160_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 ); mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
mbedtls_ripemd160( (const unsigned char *) ripemd160_test_input[i], ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
strlen( ripemd160_test_input[i] ), ripemd160_test_strlen[i], output );
output ); if( ret != 0 )
goto fail;
if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto fail;
return( 1 );
} }
if( verbose != 0 ) if( verbose != 0 )
@ -462,6 +545,12 @@ int mbedtls_ripemd160_self_test( int verbose )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
return( 0 ); return( 0 );
fail:
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
} }
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */

File diff suppressed because it is too large Load diff

489
dll/3rdparty/mbedtls/rsa_internal.c vendored Normal file
View file

@ -0,0 +1,489 @@
/*
* Helper functions for the RSA module
*
* Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#include "mbedtls/bignum.h"
#include "mbedtls/rsa_internal.h"
/*
* Compute RSA prime factors from public and private exponents
*
* Summary of algorithm:
* Setting F := lcm(P-1,Q-1), the idea is as follows:
*
* (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2)
* is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the
* square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four
* possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1)
* or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime
* factors of N.
*
* (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same
* construction still applies since (-)^K is the identity on the set of
* roots of 1 in Z/NZ.
*
* The public and private key primitives (-)^E and (-)^D are mutually inverse
* bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e.
* if and only if DE - 1 is a multiple of F, say DE - 1 = F * L.
* Splitting L = 2^t * K with K odd, we have
*
* DE - 1 = FL = (F/2) * (2^(t+1)) * K,
*
* so (F / 2) * K is among the numbers
*
* (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord
*
* where ord is the order of 2 in (DE - 1).
* We can therefore iterate through these numbers apply the construction
* of (a) and (b) above to attempt to factor N.
*
*/
int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N,
mbedtls_mpi const *E, mbedtls_mpi const *D,
mbedtls_mpi *P, mbedtls_mpi *Q )
{
int ret = 0;
uint16_t attempt; /* Number of current attempt */
uint16_t iter; /* Number of squares computed in the current attempt */
uint16_t order; /* Order of 2 in DE - 1 */
mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */
mbedtls_mpi K; /* Temporary holding the current candidate */
const unsigned char primes[] = { 2,
3, 5, 7, 11, 13, 17, 19, 23,
29, 31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97,
101, 103, 107, 109, 113, 127, 131, 137,
139, 149, 151, 157, 163, 167, 173, 179,
181, 191, 193, 197, 199, 211, 223, 227,
229, 233, 239, 241, 251
};
const size_t num_primes = sizeof( primes ) / sizeof( *primes );
if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 ||
mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
mbedtls_mpi_cmp_mpi( D, N ) >= 0 ||
mbedtls_mpi_cmp_int( E, 1 ) <= 0 ||
mbedtls_mpi_cmp_mpi( E, N ) >= 0 )
{
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
}
/*
* Initializations and temporary changes
*/
mbedtls_mpi_init( &K );
mbedtls_mpi_init( &T );
/* T := DE - 1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, D, E ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &T, &T, 1 ) );
if( ( order = (uint16_t) mbedtls_mpi_lsb( &T ) ) == 0 )
{
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
goto cleanup;
}
/* After this operation, T holds the largest odd divisor of DE - 1. */
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &T, order ) );
/*
* Actual work
*/
/* Skip trying 2 if N == 1 mod 8 */
attempt = 0;
if( N->p[0] % 8 == 1 )
attempt = 1;
for( ; attempt < num_primes; ++attempt )
{
mbedtls_mpi_lset( &K, primes[attempt] );
/* Check if gcd(K,N) = 1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) );
if( mbedtls_mpi_cmp_int( P, 1 ) != 0 )
continue;
/* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ...
* and check whether they have nontrivial GCD with N. */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &K, &K, &T, N,
Q /* temporarily use Q for storing Montgomery
* multiplication helper values */ ) );
for( iter = 1; iter <= order; ++iter )
{
/* If we reach 1 prematurely, there's no point
* in continuing to square K */
if( mbedtls_mpi_cmp_int( &K, 1 ) == 0 )
break;
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) );
if( mbedtls_mpi_cmp_int( P, 1 ) == 1 &&
mbedtls_mpi_cmp_mpi( P, N ) == -1 )
{
/*
* Have found a nontrivial divisor P of N.
* Set Q := N / P.
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( Q, NULL, N, P ) );
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &K ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, N ) );
}
/*
* If we get here, then either we prematurely aborted the loop because
* we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must
* be 1 if D,E,N were consistent.
* Check if that's the case and abort if not, to avoid very long,
* yet eventually failing, computations if N,D,E were not sane.
*/
if( mbedtls_mpi_cmp_int( &K, 1 ) != 0 )
{
break;
}
}
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
cleanup:
mbedtls_mpi_free( &K );
mbedtls_mpi_free( &T );
return( ret );
}
/*
* Given P, Q and the public exponent E, deduce D.
* This is essentially a modular inversion.
*/
int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P,
mbedtls_mpi const *Q,
mbedtls_mpi const *E,
mbedtls_mpi *D )
{
int ret = 0;
mbedtls_mpi K, L;
if( D == NULL || mbedtls_mpi_cmp_int( D, 0 ) != 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ||
mbedtls_mpi_cmp_int( E, 0 ) == 0 )
{
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
}
mbedtls_mpi_init( &K );
mbedtls_mpi_init( &L );
/* Temporarily put K := P-1 and L := Q-1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) );
/* Temporarily put D := gcd(P-1, Q-1) */
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( D, &K, &L ) );
/* K := LCM(P-1, Q-1) */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &L ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &K, NULL, &K, D ) );
/* Compute modular inverse of E in LCM(P-1, Q-1) */
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( D, E, &K ) );
cleanup:
mbedtls_mpi_free( &K );
mbedtls_mpi_free( &L );
return( ret );
}
/*
* Check that RSA CRT parameters are in accordance with core parameters.
*/
int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
const mbedtls_mpi *D, const mbedtls_mpi *DP,
const mbedtls_mpi *DQ, const mbedtls_mpi *QP )
{
int ret = 0;
mbedtls_mpi K, L;
mbedtls_mpi_init( &K );
mbedtls_mpi_init( &L );
/* Check that DP - D == 0 mod P - 1 */
if( DP != NULL )
{
if( P == NULL )
{
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DP, D ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) );
if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
}
/* Check that DQ - D == 0 mod Q - 1 */
if( DQ != NULL )
{
if( Q == NULL )
{
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DQ, D ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) );
if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
}
/* Check that QP * Q - 1 == 0 mod P */
if( QP != NULL )
{
if( P == NULL || Q == NULL )
{
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, QP, Q ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, P ) );
if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
}
cleanup:
/* Wrap MPI error codes by RSA check failure error code */
if( ret != 0 &&
ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED &&
ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
{
ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
}
mbedtls_mpi_free( &K );
mbedtls_mpi_free( &L );
return( ret );
}
/*
* Check that core RSA parameters are sane.
*/
int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P,
const mbedtls_mpi *Q, const mbedtls_mpi *D,
const mbedtls_mpi *E,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret = 0;
mbedtls_mpi K, L;
mbedtls_mpi_init( &K );
mbedtls_mpi_init( &L );
/*
* Step 1: If PRNG provided, check that P and Q are prime
*/
#if defined(MBEDTLS_GENPRIME)
if( f_rng != NULL && P != NULL &&
( ret = mbedtls_mpi_is_prime( P, f_rng, p_rng ) ) != 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
if( f_rng != NULL && Q != NULL &&
( ret = mbedtls_mpi_is_prime( Q, f_rng, p_rng ) ) != 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
#else
((void) f_rng);
((void) p_rng);
#endif /* MBEDTLS_GENPRIME */
/*
* Step 2: Check that 1 < N = P * Q
*/
if( P != NULL && Q != NULL && N != NULL )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) );
if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 ||
mbedtls_mpi_cmp_mpi( &K, N ) != 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
}
/*
* Step 3: Check and 1 < D, E < N if present.
*/
if( N != NULL && D != NULL && E != NULL )
{
if ( mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
mbedtls_mpi_cmp_int( E, 1 ) <= 0 ||
mbedtls_mpi_cmp_mpi( D, N ) >= 0 ||
mbedtls_mpi_cmp_mpi( E, N ) >= 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
}
/*
* Step 4: Check that D, E are inverse modulo P-1 and Q-1
*/
if( P != NULL && Q != NULL && D != NULL && E != NULL )
{
if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
mbedtls_mpi_cmp_int( Q, 1 ) <= 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
/* Compute DE-1 mod P-1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
/* Compute DE-1 mod Q-1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
{
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup;
}
}
cleanup:
mbedtls_mpi_free( &K );
mbedtls_mpi_free( &L );
/* Wrap MPI error codes by RSA check failure error code */
if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED )
{
ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
}
return( ret );
}
int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
const mbedtls_mpi *D, mbedtls_mpi *DP,
mbedtls_mpi *DQ, mbedtls_mpi *QP )
{
int ret = 0;
mbedtls_mpi K;
mbedtls_mpi_init( &K );
/* DP = D mod P-1 */
if( DP != NULL )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, D, &K ) );
}
/* DQ = D mod Q-1 */
if( DQ != NULL )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, D, &K ) );
}
/* QP = Q^{-1} mod P */
if( QP != NULL )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( QP, Q, P ) );
}
cleanup:
mbedtls_mpi_free( &K );
return( ret );
}
#endif /* MBEDTLS_RSA_C */

View file

@ -99,7 +99,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;
@ -109,10 +109,20 @@ 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_DEPRECATED_REMOVED)
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
{
mbedtls_sha1_starts_ret( ctx );
}
#endif
#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;
@ -266,19 +276,32 @@ 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 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_sha1_process( ctx, data );
}
#endif
#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;
@ -292,7 +315,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;
@ -300,68 +326,132 @@ 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] = #if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
const unsigned char *input,
size_t ilen )
{ {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, mbedtls_sha1_update_ret( ctx, input, ilen );
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* /*
* 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] )
{ {
uint32_t last, padn; int ret;
uint32_t used;
uint32_t high, low; uint32_t high, low;
unsigned char msglen[8];
/*
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
*/
used = ctx->total[0] & 0x3F;
ctx->buffer[used++] = 0x80;
if( used <= 56 )
{
/* Enough room for padding + length in current block */
memset( ctx->buffer + used, 0, 56 - used );
}
else
{
/* We'll need an extra block */
memset( ctx->buffer + used, 0, 64 - used );
if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
memset( ctx->buffer, 0, 56 );
}
/*
* Add message length
*/
high = ( ctx->total[0] >> 29 ) high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 ); | ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 ); low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 ); PUT_UINT32_BE( high, ctx->buffer, 56 );
PUT_UINT32_BE( low, msglen, 4 ); PUT_UINT32_BE( low, ctx->buffer, 60 );
last = ctx->total[0] & 0x3F; if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); return( ret );
mbedtls_sha1_update( ctx, sha1_padding, padn );
mbedtls_sha1_update( ctx, msglen, 8 );
/*
* Output final state
*/
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 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
unsigned char output[20] )
{
mbedtls_sha1_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_SHA1_ALT */ #endif /* !MBEDTLS_SHA1_ALT */
/* /*
* 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_DEPRECATED_REMOVED)
void mbedtls_sha1( const unsigned char *input,
size_t ilen,
unsigned char output[20] )
{
mbedtls_sha1_ret( input, ilen, output );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* FIPS-180-1 test vectors * FIPS-180-1 test vectors
@ -373,7 +463,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
}; };
@ -408,28 +498,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], {
ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i],
sha1_test_buflen[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 )
@ -439,6 +536,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 );

View file

@ -102,7 +102,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;
@ -133,8 +133,18 @@ void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
} }
ctx->is224 = is224; ctx->is224 = is224;
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
int is224 )
{
mbedtls_sha256_starts_ret( ctx, is224 );
}
#endif
#if !defined(MBEDTLS_SHA256_PROCESS_ALT) #if !defined(MBEDTLS_SHA256_PROCESS_ALT)
static const uint32_t K[] = static const uint32_t K[] =
{ {
@ -181,7 +191,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];
@ -234,20 +245,32 @@ 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 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_sha256_process( ctx, data );
}
#endif
#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,
const unsigned char *input,
size_t ilen ) 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;
@ -261,7 +284,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;
@ -269,45 +295,77 @@ 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] = #if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
const unsigned char *input,
size_t ilen )
{ {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, mbedtls_sha256_update_ret( ctx, input, ilen );
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* /*
* 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] )
{ {
uint32_t last, padn; int ret;
uint32_t used;
uint32_t high, low; uint32_t high, low;
unsigned char msglen[8];
/*
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
*/
used = ctx->total[0] & 0x3F;
ctx->buffer[used++] = 0x80;
if( used <= 56 )
{
/* Enough room for padding + length in current block */
memset( ctx->buffer + used, 0, 56 - used );
}
else
{
/* We'll need an extra block */
memset( ctx->buffer + used, 0, 64 - used );
if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
memset( ctx->buffer, 0, 56 );
}
/*
* Add message length
*/
high = ( ctx->total[0] >> 29 ) high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 ); | ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 ); low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 ); PUT_UINT32_BE( high, ctx->buffer, 56 );
PUT_UINT32_BE( low, msglen, 4 ); PUT_UINT32_BE( low, ctx->buffer, 60 );
last = ctx->total[0] & 0x3F; if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); return( ret );
mbedtls_sha256_update( ctx, sha256_padding, padn );
mbedtls_sha256_update( ctx, msglen, 8 );
/*
* Output final state
*/
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 );
@ -318,25 +376,58 @@ 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 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
unsigned char output[32] )
{
mbedtls_sha256_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_SHA256_ALT */ #endif /* !MBEDTLS_SHA256_ALT */
/* /*
* 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_DEPRECATED_REMOVED)
void mbedtls_sha256( const unsigned char *input,
size_t ilen,
unsigned char output[32],
int is224 )
{
mbedtls_sha256_ret( input, ilen, output, is224 );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
* FIPS-180-2 test vectors * FIPS-180-2 test vectors
@ -348,7 +439,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
}; };
@ -417,28 +508,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], {
ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
sha256_test_buflen[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 )
@ -448,6 +548,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 );

View file

@ -116,7 +116,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;
@ -147,8 +147,18 @@ void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
} }
ctx->is384 = is384; ctx->is384 = is384;
return( 0 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
int is384 )
{
mbedtls_sha512_starts_ret( ctx, is384 );
}
#endif
#if !defined(MBEDTLS_SHA512_PROCESS_ALT) #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
/* /*
@ -198,7 +208,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];
@ -265,20 +276,32 @@ 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 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
const unsigned char data[128] )
{
mbedtls_internal_sha512_process( ctx, data );
}
#endif
#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,
const unsigned char *input,
size_t ilen ) 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;
@ -291,7 +314,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;
@ -299,49 +325,77 @@ 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] = #if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
const unsigned char *input,
size_t ilen )
{ {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, mbedtls_sha512_update_ret( ctx, input, ilen );
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* /*
* 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] )
{ {
size_t last, padn; int ret;
unsigned used;
uint64_t high, low; uint64_t high, low;
unsigned char msglen[16];
/*
* Add padding: 0x80 then 0x00 until 16 bytes remain for the length
*/
used = ctx->total[0] & 0x7F;
ctx->buffer[used++] = 0x80;
if( used <= 112 )
{
/* Enough room for padding + length in current block */
memset( ctx->buffer + used, 0, 112 - used );
}
else
{
/* We'll need an extra block */
memset( ctx->buffer + used, 0, 128 - used );
if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
memset( ctx->buffer, 0, 112 );
}
/*
* Add message length
*/
high = ( ctx->total[0] >> 61 ) high = ( ctx->total[0] >> 61 )
| ( ctx->total[1] << 3 ); | ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 ); low = ( ctx->total[0] << 3 );
PUT_UINT64_BE( high, msglen, 0 ); PUT_UINT64_BE( high, ctx->buffer, 112 );
PUT_UINT64_BE( low, msglen, 8 ); PUT_UINT64_BE( low, ctx->buffer, 120 );
last = (size_t)( ctx->total[0] & 0x7F ); if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); return( ret );
mbedtls_sha512_update( ctx, sha512_padding, padn );
mbedtls_sha512_update( ctx, msglen, 16 );
/*
* Output final state
*/
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 );
PUT_UINT64_BE( ctx->state[2], output, 16 ); PUT_UINT64_BE( ctx->state[2], output, 16 );
@ -354,25 +408,58 @@ 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 );
} }
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
unsigned char output[64] )
{
mbedtls_sha512_finish_ret( ctx, output );
}
#endif
#endif /* !MBEDTLS_SHA512_ALT */ #endif /* !MBEDTLS_SHA512_ALT */
/* /*
* 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_DEPRECATED_REMOVED)
void mbedtls_sha512( const unsigned char *input,
size_t ilen,
unsigned char output[64],
int is384 )
{
mbedtls_sha512_ret( input, ilen, output, is384 );
}
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/* /*
@ -386,7 +473,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
}; };
@ -473,28 +560,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], {
ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
sha512_test_buflen[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 )
@ -504,6 +598,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 );

View file

@ -323,6 +323,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 */

View file

@ -1839,7 +1839,8 @@ mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphers
#endif /* MBEDTLS_PK_C */ #endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ) int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
{ {
switch( info->key_exchange ) switch( info->key_exchange )
@ -1849,13 +1850,14 @@ int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
return( 1 ); return( 1 );
default: default:
return( 0 ); return( 0 );
} }
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ) int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )

View file

@ -82,6 +82,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) {
@ -98,6 +105,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 );
@ -128,6 +136,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;
@ -708,6 +719,49 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
return( 0 ); return( 0 );
} }
/**
* \brief Validate cipher suite against config in SSL context.
*
* \param suite_info cipher suite to validate
* \param ssl SSL context
* \param min_minor_ver Minimal minor version to accept a cipher suite
* \param max_minor_ver Maximal minor version to accept a cipher suite
*
* \return 0 if valid, else 1
*/
static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_info,
const mbedtls_ssl_context * ssl,
int min_minor_ver, int max_minor_ver )
{
(void) ssl;
if( suite_info == NULL )
return( 1 );
if( suite_info->min_minor_ver > max_minor_ver ||
suite_info->max_minor_ver < min_minor_ver )
return( 1 );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
return( 1 );
#endif
#if defined(MBEDTLS_ARC4_C)
if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
return( 1 );
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
return( 1 );
#endif
return( 0 );
}
static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{ {
int ret; int ret;
@ -717,6 +771,10 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
unsigned char offer_compress; unsigned char offer_compress;
const int *ciphersuites; const int *ciphersuites;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
int uses_ec = 0;
#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
@ -860,39 +918,26 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{ {
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] ); ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
if( ciphersuite_info == NULL ) if( ssl_validate_ciphersuite( ciphersuite_info, ssl,
ssl->conf->min_minor_ver,
ssl->conf->max_minor_ver ) != 0 )
continue; continue;
if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
continue;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
continue;
#endif
#if defined(MBEDTLS_ARC4_C)
if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
continue;
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
continue;
#endif
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x", MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
ciphersuites[i] ) ); ciphersuites[i] ) );
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info );
#endif
n++; n++;
*p++ = (unsigned char)( ciphersuites[i] >> 8 ); *p++ = (unsigned char)( ciphersuites[i] >> 8 );
*p++ = (unsigned char)( ciphersuites[i] ); *p++ = (unsigned char)( ciphersuites[i] );
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) );
/* /*
* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
*/ */
@ -900,6 +945,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
#endif #endif
{ {
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) );
*p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
*p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
n++; n++;
@ -919,8 +965,6 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
*q++ = (unsigned char)( n >> 7 ); *q++ = (unsigned char)( n >> 7 );
*q++ = (unsigned char)( n << 1 ); *q++ = (unsigned char)( n << 1 );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
#if defined(MBEDTLS_ZLIB_SUPPORT) #if defined(MBEDTLS_ZLIB_SUPPORT)
offer_compress = 1; offer_compress = 1;
#else #else
@ -928,7 +972,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
#endif #endif
/* /*
* We don't support compression with DTLS right now: is many records come * We don't support compression with DTLS right now: if many records come
* in the same datagram, uncompressing one could overwrite the next one. * in the same datagram, uncompressing one could overwrite the next one.
* We don't want to add complexity for handling that case unless there is * We don't want to add complexity for handling that case unless there is
* an actual need for it. * an actual need for it.
@ -965,6 +1009,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;
@ -978,11 +1024,14 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( uses_ec )
{
ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
}
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@ -1215,14 +1264,14 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
size_t list_size; size_t list_size;
const unsigned char *p; const unsigned char *p;
list_size = buf[0]; if( len == 0 || (size_t)( buf[0] + 1 ) != len )
if( list_size + 1 != len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
list_size = buf[0];
p = buf + 1; p = buf + 1;
while( list_size > 0 ) while( list_size > 0 )
@ -1442,9 +1491,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" ) );
@ -1547,13 +1593,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 );
@ -1683,22 +1727,9 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ); /*
if( suite_info == NULL * Perform cipher suite validation in same way as in ssl_write_client_hello.
#if defined(MBEDTLS_ARC4_C) */
|| ( ssl->conf->arc4_disabled &&
suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
#endif
)
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
i = 0; i = 0;
while( 1 ) while( 1 )
{ {
@ -1717,6 +1748,17 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
} }
} }
suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, ssl->minor_ver ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
if( comp != MBEDTLS_SSL_COMPRESS_NULL if( comp != MBEDTLS_SSL_COMPRESS_NULL
#if defined(MBEDTLS_ZLIB_SUPPORT) #if defined(MBEDTLS_ZLIB_SUPPORT)
&& comp != MBEDTLS_SSL_COMPRESS_DEFLATE && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
@ -2051,10 +2093,16 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
* *
* opaque psk_identity_hint<0..2^16-1>; * opaque psk_identity_hint<0..2^16-1>;
*/ */
if( (*p) > end - 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
"(psk_identity_hint length)" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
len = (*p)[0] << 8 | (*p)[1]; len = (*p)[0] << 8 | (*p)[1];
*p += 2; *p += 2;
if( (*p) + len > end ) if( (*p) > end - len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
"(psk_identity_hint length)" ) ); "(psk_identity_hint length)" ) );
@ -2260,7 +2308,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" ) );
@ -2472,10 +2520,17 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
/* /*
* Read signature * Read signature
*/ */
if( p > end - 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
sig_len = ( p[0] << 8 ) | p[1]; sig_len = ( p[0] << 8 ) | p[1];
p += 2; p += 2;
if( end != p + sig_len ) if( p != end - sig_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@ -2492,39 +2547,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 || \
@ -2533,35 +2560,13 @@ 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 || \
MBEDTLS_SSL_PROTO_TLS1_2 */ MBEDTLS_SSL_PROTO_TLS1_2 */
@ -2702,10 +2707,27 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
buf = ssl->in_msg; buf = ssl->in_msg;
/* certificate_types */ /* certificate_types */
if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
}
cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )]; cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
n = cert_type_len; n = cert_type_len;
if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) /*
* In the subsequent code there are two paths that read from buf:
* * the length of the signature algorithms field (if minor version of
* SSL is 3),
* * distinguished name length otherwise.
* Both reach at most the index:
* ...hdr_len + 2 + n,
* therefore the buffer length at this point must be greater than that
* regardless of the actual code path.
*/
if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@ -2720,9 +2742,32 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
#if defined(MBEDTLS_DEBUG_C) #if defined(MBEDTLS_DEBUG_C)
unsigned char* sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n; unsigned char* sig_alg;
size_t i; size_t i;
#endif
/*
* The furthest access in buf is in the loop few lines below:
* sig_alg[i + 1],
* where:
* sig_alg = buf + ...hdr_len + 3 + n,
* max(i) = sig_alg_len - 1.
* Therefore the furthest access is:
* buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1],
* which reduces to:
* buf[...hdr_len + 3 + n + sig_alg_len],
* which is one less than we need the buf to be.
*/
if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
}
#if defined(MBEDTLS_DEBUG_C)
sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
for( i = 0; i < sig_alg_len; i += 2 ) for( i = 0; i < sig_alg_len; i += 2 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d" MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d"
@ -2731,14 +2776,6 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
#endif #endif
n += 2 + sig_alg_len; n += 2 + sig_alg_len;
if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
}
} }
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@ -3292,7 +3329,7 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) | lifetime = ( ((uint32_t) msg[0]) << 24 ) | ( msg[1] << 16 ) |
( msg[2] << 8 ) | ( msg[3] ); ( msg[2] << 8 ) | ( msg[3] );
ticket_len = ( msg[4] << 8 ) | ( msg[5] ); ticket_len = ( msg[4] << 8 ) | ( msg[5] );

View file

@ -99,6 +99,13 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) );
if( len < 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
if( servername_list_size + 2 != len ) if( servername_list_size + 2 != len )
{ {
@ -109,7 +116,7 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
} }
p = buf + 2; p = buf + 2;
while( servername_list_size > 0 ) while( servername_list_size > 2 )
{ {
hostname_len = ( ( p[1] << 8 ) | p[2] ); hostname_len = ( ( p[1] << 8 ) | p[2] );
if( hostname_len + 3 > servername_list_size ) if( hostname_len + 3 > servername_list_size )
@ -213,6 +220,12 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
mbedtls_md_type_t md_cur; mbedtls_md_type_t md_cur;
mbedtls_pk_type_t sig_cur; mbedtls_pk_type_t sig_cur;
if ( len < 2 ) {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
if( sig_alg_list_size + 2 != len || if( sig_alg_list_size + 2 != len ||
sig_alg_list_size % 2 != 0 ) sig_alg_list_size % 2 != 0 )
@ -281,6 +294,12 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
const unsigned char *p; const unsigned char *p;
const mbedtls_ecp_curve_info *curve_info, **curves; const mbedtls_ecp_curve_info *curve_info, **curves;
if ( len < 2 ) {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
if( list_size + 2 != len || if( list_size + 2 != len ||
list_size % 2 != 0 ) list_size % 2 != 0 )
@ -340,14 +359,14 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
size_t list_size; size_t list_size;
const unsigned char *p; const unsigned char *p;
list_size = buf[0]; if( len == 0 || (size_t)( buf[0] + 1 ) != len )
if( list_size + 1 != len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
list_size = buf[0];
p = buf + 1; p = buf + 1;
while( list_size > 0 ) while( list_size > 0 )
@ -605,25 +624,22 @@ 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( ours = ssl->conf->alpn_list; *ours != NULL; 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 */ cur_len = *theirs++;
if( theirs > end )
/* 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_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
cur_len = *theirs++;
/* Empty strings MUST NOT be included */ /* Empty strings MUST NOT be included */
if( cur_len == 0 ) if( cur_len == 0 )
{ {
@ -631,6 +647,17 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
}
/*
* Use our order of preference
*/
for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ )
{
ours_len = strlen( *ours );
for( theirs = start; theirs != end; theirs += cur_len )
{
cur_len = *theirs++;
if( cur_len == ours_len && if( cur_len == ours_len &&
memcmp( theirs, *ours, cur_len ) == 0 ) memcmp( theirs, *ours, cur_len ) == 0 )
@ -1656,10 +1683,16 @@ read_record_header:
while( ext_len != 0 ) while( ext_len != 0 )
{ {
unsigned int ext_id = ( ( ext[0] << 8 ) unsigned int ext_id;
| ( ext[1] ) ); unsigned int ext_size;
unsigned int ext_size = ( ( ext[2] << 8 ) if ( ext_len < 4 ) {
| ( ext[3] ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
ext_id = ( ( ext[0] << 8 ) | ( ext[1] ) );
ext_size = ( ( ext[2] << 8 ) | ( ext[3] ) );
if( ext_size + 4 > ext_len ) if( ext_size + 4 > ext_len )
{ {
@ -1697,10 +1730,7 @@ read_record_header:
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
case MBEDTLS_TLS_EXT_SIG_ALG: case MBEDTLS_TLS_EXT_SIG_ALG:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
break;
#endif
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
@ -2047,7 +2077,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;
@ -2567,8 +2597,12 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if ( mbedtls_ssl_ciphersuite_uses_ec(
mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ) ) )
{
ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
}
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@ -2840,7 +2874,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
unsigned char *p = ssl->out_msg + 4; unsigned char *p = ssl->out_msg + 4;
size_t len; size_t len = 0;
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
unsigned char *dig_signed = p; unsigned char *dig_signed = p;
size_t dig_signed_len = 0; size_t dig_signed_len = 0;
@ -2942,10 +2976,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 );
} }
@ -3098,40 +3133,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 || \
@ -3140,33 +3147,15 @@ 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 || \
MBEDTLS_SSL_PROTO_TLS1_2 */ MBEDTLS_SSL_PROTO_TLS1_2 */
@ -3347,6 +3336,10 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
defined(MBEDTLS_SSL_PROTO_TLS1_2) defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
if ( p + 2 > end ) {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
if( *p++ != ( ( len >> 8 ) & 0xFF ) || if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
*p++ != ( ( len ) & 0xFF ) ) *p++ != ( ( len ) & 0xFF ) )
{ {
@ -3438,7 +3431,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 );
@ -3447,7 +3440,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 );

File diff suppressed because it is too large Load diff

View file

@ -113,8 +113,12 @@ void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t *
mbedtls_mutex_lock = mutex_lock; mbedtls_mutex_lock = mutex_lock;
mbedtls_mutex_unlock = mutex_unlock; mbedtls_mutex_unlock = mutex_unlock;
#if defined(MBEDTLS_FS_IO)
mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); mbedtls_mutex_init( &mbedtls_threading_readdir_mutex );
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE)
mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex );
#endif
} }
/* /*
@ -122,8 +126,12 @@ void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t *
*/ */
void mbedtls_threading_free_alt( void ) void mbedtls_threading_free_alt( void )
{ {
#if defined(MBEDTLS_FS_IO)
mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); mbedtls_mutex_free( &mbedtls_threading_readdir_mutex );
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE)
mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex );
#endif
} }
#endif /* MBEDTLS_THREADING_ALT */ #endif /* MBEDTLS_THREADING_ALT */
@ -133,7 +141,11 @@ void mbedtls_threading_free_alt( void )
#ifndef MUTEX_INIT #ifndef MUTEX_INIT
#define MUTEX_INIT #define MUTEX_INIT
#endif #endif
#if defined(MBEDTLS_FS_IO)
mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT;
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE)
mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT;
#endif
#endif /* MBEDTLS_THREADING_C */ #endif /* MBEDTLS_THREADING_C */

View file

@ -246,21 +246,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 );
}
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 ); 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 */
@ -278,6 +280,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 ) );
@ -287,23 +297,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;
gettimeofday( &now, NULL );
delta = ( now.tv_sec - t->start.tv_sec ) * 1000ul
+ ( now.tv_usec - t->start.tv_usec ) / 1000;
return( delta ); return( delta );
}
} }
static void sighandler( int signum ) static void sighandler( int signum )
@ -317,6 +326,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 */
@ -381,12 +396,20 @@ static void busy_msleep( unsigned long msec )
} }
#define FAIL do \ #define FAIL do \
{ \ { \
if( verbose != 0 ) \ if( verbose != 0 ) \
mbedtls_printf( "failed\n" ); \ { \
\ mbedtls_printf( "failed at line %d\n", __LINE__ ); \
mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \
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 ); \ return( 1 ); \
} while( 0 ) } while( 0 )
/* /*
* Checkup routine * Checkup routine
@ -396,22 +419,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 );
@ -423,12 +446,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 )
@ -437,29 +455,23 @@ 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 ); busy_msleep( a - a / 4 ); /* T = a - a/4 */
if( mbedtls_timing_get_delay( &ctx ) != 0 ) if( mbedtls_timing_get_delay( &ctx ) != 0 )
FAIL; FAIL;
busy_msleep( a / 4 ); 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 - a / 8 - b / 8 ); busy_msleep( b ); /* T = a + b + b/4 */
if( mbedtls_timing_get_delay( &ctx ) != 1 )
FAIL;
busy_msleep( 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 );
busy_msleep( 200 ); busy_msleep( 200 );
@ -477,7 +489,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 )

View file

@ -98,12 +98,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 */
@ -116,6 +128,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 */
@ -125,6 +140,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 */
@ -170,6 +188,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 */
@ -437,6 +470,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
"MBEDTLS_SSL_TRUNCATED_HMAC", "MBEDTLS_SSL_TRUNCATED_HMAC",
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
"MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
#if defined(MBEDTLS_THREADING_ALT) #if defined(MBEDTLS_THREADING_ALT)
"MBEDTLS_THREADING_ALT", "MBEDTLS_THREADING_ALT",
#endif /* MBEDTLS_THREADING_ALT */ #endif /* MBEDTLS_THREADING_ALT */

View file

@ -72,15 +72,6 @@
#include <time.h> #include <time.h>
#endif #endif
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#if !defined(_WIN32)
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#endif
#endif
#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }
#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } #define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); }
@ -498,9 +489,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 );
@ -510,17 +502,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 );
} }

View file

@ -97,17 +97,23 @@ static int x509_crl_get_version( unsigned char **p,
} }
/* /*
* X.509 CRL v2 extensions (no extensions parsed yet.) * X.509 CRL v2 extensions
*
* We currently don't parse any extension's content, but we do check that the
* list of extensions is well-formed and abort on critical extensions (that
* are unsupported as we don't support any extension so far)
*/ */
static int x509_get_crl_ext( unsigned char **p, static int x509_get_crl_ext( unsigned char **p,
const unsigned char *end, const unsigned char *end,
mbedtls_x509_buf *ext ) mbedtls_x509_buf *ext )
{ {
int ret; int ret;
size_t len = 0;
/* Get explicit tag */ /*
if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0) ) != 0 ) * crlExtensions [0] EXPLICIT Extensions OPTIONAL
* -- if present, version MUST be v2
*/
if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 )
{ {
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
return( 0 ); return( 0 );
@ -117,11 +123,54 @@ static int x509_get_crl_ext( unsigned char **p,
while( *p < end ) while( *p < end )
{ {
/*
* Extension ::= SEQUENCE {
* extnID OBJECT IDENTIFIER,
* critical BOOLEAN DEFAULT FALSE,
* extnValue OCTET STRING }
*/
int is_critical = 0;
const unsigned char *end_ext_data;
size_t len;
/* Get enclosing sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
end_ext_data = *p + len;
/* Get OID (currently ignored) */
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
MBEDTLS_ASN1_OID ) ) != 0 )
{
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
}
*p += len; *p += len;
/* Get optional critical */
if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data,
&is_critical ) ) != 0 &&
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
{
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
}
/* Data should be octet string type */
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
/* Ignore data so far and just check its length */
*p += len;
if( *p != end_ext_data )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
/* Abort on (unsupported) critical extensions */
if( is_critical )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
} }
if( *p != end ) if( *p != end )
@ -259,7 +308,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
{ {
int ret; int ret;
size_t len; size_t len;
unsigned char *p, *end; unsigned char *p = NULL, *end = NULL;
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
mbedtls_x509_crl *crl = chain; mbedtls_x509_crl *crl = chain;
@ -296,7 +345,11 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
/* /*
* Copy raw DER-encoded CRL * Copy raw DER-encoded CRL
*/ */
if( ( p = mbedtls_calloc( 1, buflen ) ) == NULL ) if( buflen == 0 )
return( MBEDTLS_ERR_X509_INVALID_FORMAT );
p = mbedtls_calloc( 1, buflen );
if( p == NULL )
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); return( MBEDTLS_ERR_X509_ALLOC_FAILED );
memcpy( p, buf, buflen ); memcpy( p, buf, buflen );

View file

@ -135,7 +135,8 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
/* Only ECDSA */ /* Only ECDSA */
MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ), MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ),
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
/* Only NIST P-256 and P-384 */ /* Only NIST P-256 and P-384 */
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
@ -153,6 +154,9 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
mbedtls_md_type_t md_alg ) mbedtls_md_type_t md_alg )
{ {
if( md_alg == MBEDTLS_MD_NONE )
return( -1 );
if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 ) if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
return( 0 ); return( 0 );
@ -166,6 +170,9 @@ static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
mbedtls_pk_type_t pk_alg ) mbedtls_pk_type_t pk_alg )
{ {
if( pk_alg == MBEDTLS_PK_NONE )
return( -1 );
if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 ) if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
return( 0 ); return( 0 );
@ -197,6 +204,9 @@ static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
{ {
mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id; mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
if( gid == MBEDTLS_ECP_DP_NONE )
return( -1 );
if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 ) if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
return( 0 ); return( 0 );
@ -474,9 +484,12 @@ static int x509_get_subject_alt_name( unsigned char **p,
if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC ) if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) !=
MBEDTLS_ASN1_CONTEXT_SPECIFIC )
{
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
}
/* Skip everything but DNS name */ /* Skip everything but DNS name */
if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
@ -556,18 +569,14 @@ static int x509_get_crt_ext( unsigned char **p,
end_ext_data = *p + len; end_ext_data = *p + len;
/* Get extension ID */ /* Get extension ID */
extn_oid.tag = **p; if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len,
MBEDTLS_ASN1_OID ) ) != 0 )
if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
extn_oid.tag = MBEDTLS_ASN1_OID;
extn_oid.p = *p; extn_oid.p = *p;
*p += extn_oid.len; *p += extn_oid.len;
if( ( end - *p ) < 1 )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_OUT_OF_DATA );
/* Get optional critical */ /* Get optional critical */
if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 && if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
@ -1632,7 +1641,7 @@ int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509
/* /*
* Check that the given certificate is not revoked according to the CRL. * Check that the given certificate is not revoked according to the CRL.
* Skip validation is no CRL for the given CA is present. * Skip validation if no CRL for the given CA is present.
*/ */
static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
mbedtls_x509_crl *crl_list, mbedtls_x509_crl *crl_list,
@ -1677,17 +1686,13 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
flags |= MBEDTLS_X509_BADCRL_BAD_PK; flags |= MBEDTLS_X509_BADCRL_BAD_PK;
md_info = mbedtls_md_info_from_type( crl_list->sig_md ); md_info = mbedtls_md_info_from_type( crl_list->sig_md );
if( md_info == NULL ) if( mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ) != 0 )
{ {
/* /* Note: this can't happen except after an internal error */
* Cannot check 'unknown' hash
*/
flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
break; break;
} }
mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 ) if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 )
flags |= MBEDTLS_X509_BADCERT_BAD_KEY; flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
@ -1899,6 +1904,27 @@ static int x509_crt_check_parent( const mbedtls_x509_crt *child,
return( 0 ); return( 0 );
} }
/*
* Verify a certificate with no parent inside the chain
* (either the parent is a trusted root, or there is no parent)
*
* See comments for mbedtls_x509_crt_verify_with_profile()
* (also for notation used below)
*
* This function is called in two cases:
* - child was found to have a parent in trusted roots, in which case we're
* called with trust_ca pointing directly to that parent (not the full list)
* - this is cases 1, 2 and 3 of the comment on verify_with_profile()
* - case 1 is special as child and trust_ca point to copies of the same
* certificate then
* - child was found to have no parent either in the chain or in trusted CAs
* - this is cases 4 and 5 of the comment on verify_with_profile()
*
* For historical reasons, the function currently does not assume that
* trust_ca points directly to the right root in the first case, and it
* doesn't know in which case it starts, so it always starts by searching for
* a parent in trust_ca.
*/
static int x509_crt_verify_top( static int x509_crt_verify_top(
mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca, mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl, mbedtls_x509_crl *ca_crl,
@ -1932,15 +1958,12 @@ static int x509_crt_verify_top(
*flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
md_info = mbedtls_md_info_from_type( child->sig_md ); md_info = mbedtls_md_info_from_type( child->sig_md );
if( md_info == NULL ) if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 )
{ {
/* /* Note: this can't happen except after an internal error */
* Cannot check 'unknown', no need to try any CA /* Cannot check signature, no need to try any CA */
*/
trust_ca = NULL; trust_ca = NULL;
} }
else
mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next )
{ {
@ -1955,7 +1978,7 @@ static int x509_crt_verify_top(
*/ */
if( child->subject_raw.len == trust_ca->subject_raw.len && if( child->subject_raw.len == trust_ca->subject_raw.len &&
memcmp( child->subject_raw.p, trust_ca->subject_raw.p, memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
child->issuer_raw.len ) == 0 ) child->subject_raw.len ) == 0 )
{ {
check_path_cnt--; check_path_cnt--;
} }
@ -2005,7 +2028,7 @@ static int x509_crt_verify_top(
if( trust_ca != NULL && if( trust_ca != NULL &&
( child->subject_raw.len != trust_ca->subject_raw.len || ( child->subject_raw.len != trust_ca->subject_raw.len ||
memcmp( child->subject_raw.p, trust_ca->subject_raw.p, memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
child->issuer_raw.len ) != 0 ) ) child->subject_raw.len ) != 0 ) )
{ {
#if defined(MBEDTLS_X509_CRL_PARSE_C) #if defined(MBEDTLS_X509_CRL_PARSE_C)
/* Check trusted CA's CRL for the chain's top crt */ /* Check trusted CA's CRL for the chain's top crt */
@ -2042,6 +2065,11 @@ static int x509_crt_verify_top(
return( 0 ); return( 0 );
} }
/*
* Verify a certificate with a parent inside the chain
*
* See comments for mbedtls_x509_crt_verify_with_profile()
*/
static int x509_crt_verify_child( static int x509_crt_verify_child(
mbedtls_x509_crt *child, mbedtls_x509_crt *parent, mbedtls_x509_crt *child, mbedtls_x509_crt *parent,
mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl,
@ -2080,17 +2108,13 @@ static int x509_crt_verify_child(
*flags |= MBEDTLS_X509_BADCERT_BAD_PK; *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
md_info = mbedtls_md_info_from_type( child->sig_md ); md_info = mbedtls_md_info_from_type( child->sig_md );
if( md_info == NULL ) if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 )
{ {
/* /* Note: this can't happen except after an internal error */
* Cannot check 'unknown' hash
*/
*flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
} }
else else
{ {
mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 ) if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 )
*flags |= MBEDTLS_X509_BADCERT_BAD_KEY; *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
@ -2191,6 +2215,34 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
/* /*
* Verify the certificate validity, with profile * Verify the certificate validity, with profile
*
* The chain building/verification is spread accross 4 functions:
* - this one
* - x509_crt_verify_child()
* - x509_crt_verify_top()
* - x509_crt_check_parent()
*
* There are five main cases to consider. Let's introduce some notation:
* - E means the end-entity certificate
* - I an intermediate CA
* - R the trusted root CA this chain anchors to
* - T the list of trusted roots (R and possible some others)
*
* The main cases with the calling sequence of the crt_verify_xxx() are:
* 1. E = R (explicitly trusted EE cert)
* verify(E, T) -> verify_top(E, R)
* 2. E -> R (EE signed by trusted root)
* verify(E, T) -> verify_top(E, R)
* 3. E -> I -> R (EE signed by intermediate signed by trusted root)
* verify(E, T) -> verify_child(E, I, T) -> verify_top(I, R)
* (plus variant with multiple intermediates)
* 4. E -> I (EE signed by intermediate that's not trusted)
* verify(E, T) -> verify_child(E, I, T) -> verify_top(I, T)
* (plus variant with multiple intermediates)
* 5. E (EE not trusted)
* verify(E, T) -> verify_top(E, T)
*
* Note: this notation and case numbering is also used in x509_crt_verify_top()
*/ */
int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca, mbedtls_x509_crt *trust_ca,

View file

@ -280,34 +280,25 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
#if defined(MBEDTLS_PEM_PARSE_C) #if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_init( &pem );
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
if( buf[buflen - 1] != '\0' ) if( buf[buflen - 1] == '\0' )
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; {
else mbedtls_pem_init( &pem );
ret = mbedtls_pem_read_buffer( &pem, ret = mbedtls_pem_read_buffer( &pem,
"-----BEGIN CERTIFICATE REQUEST-----", "-----BEGIN CERTIFICATE REQUEST-----",
"-----END CERTIFICATE REQUEST-----", "-----END CERTIFICATE REQUEST-----",
buf, NULL, 0, &use_len ); buf, NULL, 0, &use_len );
if( ret == 0 ) if( ret == 0 )
{
/* /*
* Was PEM encoded, parse the result * Was PEM encoded, parse the result
*/ */
if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 ) ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen );
return( ret );
mbedtls_pem_free( &pem ); mbedtls_pem_free( &pem );
return( 0 ); if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
}
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{
mbedtls_pem_free( &pem );
return( ret ); return( ret );
} }
else
#endif /* MBEDTLS_PEM_PARSE_C */ #endif /* MBEDTLS_PEM_PARSE_C */
return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) ); return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
} }

View file

@ -53,7 +53,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;
@ -67,7 +67,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 )
@ -179,8 +179,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 ) );
@ -195,14 +198,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 ) );
@ -214,7 +220,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 */
@ -315,9 +321,15 @@ 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 )
@ -328,6 +340,10 @@ 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
*/ */
/* Only for v3 */
if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 )
{
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); 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 ) ); 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 |
@ -335,6 +351,7 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
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_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); MBEDTLS_ASN1_CONSTRUCTED | 3 ) );
}
/* /*
* SubjectPublicKeyInfo * SubjectPublicKeyInfo
@ -386,12 +403,17 @@ 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) }
*/ */
/* Can be omitted for v1 */
if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 )
{
sub_len = 0; sub_len = 0;
MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) ); MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) );
len += sub_len; 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_len( &c, tmp_buf, sub_len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); 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 |
@ -400,7 +422,11 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
/* /*
* 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 )

View file

@ -52,7 +52,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 )
@ -60,7 +60,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 )
@ -196,13 +196,20 @@ 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( pk_alg == MBEDTLS_PK_ECKEY )
pk_alg = MBEDTLS_PK_ECDSA;
if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
f_rng, p_rng ) ) != 0 || f_rng, p_rng ) ) != 0 )
( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, {
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;
else
return( MBEDTLS_ERR_X509_INVALID_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 );

View file

@ -1,9 +1,18 @@
/** /**
* \file aes.h * \file aes.h
* *
* \brief AES block cipher * \brief The Advanced Encryption Standard (AES) specifies a FIPS-approved
* cryptographic algorithm that can be used to protect electronic
* data.
* *
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * The AES algorithm is a symmetric block cipher that can
* encrypt and decrypt information. For more information, see
* <em>FIPS Publication 197: Advanced Encryption Standard</em> and
* <em>ISO/IEC 18033-2:2006: Information technology -- Security
* techniques -- Encryption algorithms -- Part 2: Asymmetric
* ciphers</em>.
*/
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,8 +29,9 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_AES_H #ifndef MBEDTLS_AES_H
#define MBEDTLS_AES_H #define MBEDTLS_AES_H
@ -35,12 +45,17 @@
#include <stdint.h> #include <stdint.h>
/* padlock.c and aesni.c rely on these values! */ /* padlock.c and aesni.c rely on these values! */
#define MBEDTLS_AES_ENCRYPT 1 #define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */
#define MBEDTLS_AES_DECRYPT 0 #define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */
/* Error codes in range 0x0020-0x0022 */
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ #define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ #define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
/* Error codes in range 0x0023-0x0025 */
#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus) !defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline
@ -55,68 +70,90 @@ extern "C" {
#endif #endif
/** /**
* \brief AES context structure * \brief The AES context-type definition.
*
* \note buf is able to hold 32 extra bytes, which can be used:
* - for alignment purposes if VIA padlock is used, and/or
* - to simplify key expansion in the 256-bit case by
* generating an extra round key
*/ */
typedef struct typedef struct
{ {
int nr; /*!< number of rounds */ int nr; /*!< The number of rounds. */
uint32_t *rk; /*!< AES round keys */ uint32_t *rk; /*!< AES round keys. */
uint32_t buf[68]; /*!< unaligned data */ uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
hold 32 extra Bytes, which can be used for
one of the following purposes:
<ul><li>Alignment if VIA padlock is
used.</li>
<li>Simplifying key expansion in the 256-bit
case by generating an extra round key.
</li></ul> */
} }
mbedtls_aes_context; mbedtls_aes_context;
/** /**
* \brief Initialize AES context * \brief This function initializes the specified AES context.
* *
* \param ctx AES context to be initialized * It must be the first API called before using
* the context.
*
* \param ctx The AES context to initialize.
*/ */
void mbedtls_aes_init( mbedtls_aes_context *ctx ); void mbedtls_aes_init( mbedtls_aes_context *ctx );
/** /**
* \brief Clear AES context * \brief This function releases and clears the specified AES context.
* *
* \param ctx AES context to be cleared * \param ctx The AES context to clear.
*/ */
void mbedtls_aes_free( mbedtls_aes_context *ctx ); void mbedtls_aes_free( mbedtls_aes_context *ctx );
/** /**
* \brief AES key schedule (encryption) * \brief This function sets the encryption key.
* *
* \param ctx AES context to be initialized * \param ctx The AES context to which the key should be bound.
* \param key encryption key * \param key The encryption key.
* \param keybits must be 128, 192 or 256 * \param keybits The size of data passed in bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
* *
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH * \return \c 0 on success or #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
* on failure.
*/ */
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits ); unsigned int keybits );
/** /**
* \brief AES key schedule (decryption) * \brief This function sets the decryption key.
* *
* \param ctx AES context to be initialized * \param ctx The AES context to which the key should be bound.
* \param key decryption key * \param key The decryption key.
* \param keybits must be 128, 192 or 256 * \param keybits The size of data passed. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
* *
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH * \return \c 0 on success, or #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/ */
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits ); unsigned int keybits );
/** /**
* \brief AES-ECB block encryption/decryption * \brief This function performs an AES single-block encryption or
* decryption operation.
* *
* \param ctx AES context * It performs the operation defined in the \p mode parameter
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT * (encrypt or decrypt), on the input data buffer defined in
* \param input 16-byte input block * the \p input parameter.
* \param output 16-byte output block
* *
* \return 0 if successful * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or
* mbedtls_aes_setkey_dec() must be called before the first
* call to this API with the same context.
*
* \param ctx The AES context to use for encryption or decryption.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param input The 16-Byte buffer holding the input data.
* \param output The 16-Byte buffer holding the output data.
* \return \c 0 on success.
*/ */
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
int mode, int mode,
@ -125,26 +162,40 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CBC) #if defined(MBEDTLS_CIPHER_MODE_CBC)
/** /**
* \brief AES-CBC buffer encryption/decryption * \brief This function performs an AES-CBC encryption or decryption operation
* Length should be a multiple of the block * on full blocks.
* size (16 bytes) *
* It performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer defined in
* the \p input parameter.
*
* It can be called as many times as needed, until all the input
* data is processed. mbedtls_aes_init(), and either
* mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
* before the first call to this API with the same context.
*
* \note This function operates on aligned blocks, that is, the input size
* must be a multiple of the AES block size of 16 Bytes.
* *
* \note Upon exit, the content of the IV is updated so that you can * \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following * call the same function again on the next
* block(s) of data and get the same result as if it was * block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage. * encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the * If you need to retain the contents of the IV, you should
* IV, you should either save it manually or use the cipher * either save it manually or use the cipher module instead.
* module instead.
* *
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
* *
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH * \param ctx The AES context to use for encryption or decryption.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of the input data in Bytes. This must be a
* multiple of the block size (16 Bytes).
* \param iv Initialization vector (updated after use).
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
*
* \return \c 0 on success, or #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
* on failure.
*/ */
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
int mode, int mode,
@ -156,29 +207,38 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CFB) #if defined(MBEDTLS_CIPHER_MODE_CFB)
/** /**
* \brief AES-CFB128 buffer encryption/decryption. * \brief This function performs an AES-CFB128 encryption or decryption
* operation.
* *
* Note: Due to the nature of CFB you should use the same key schedule for * It performs the operation defined in the \p mode
* both encryption and decryption. So a context initialized with * parameter (encrypt or decrypt), on the input data buffer
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. * defined in the \p input parameter.
*
* For CFB, you must set up the context with mbedtls_aes_setkey_enc(),
* regardless of whether you are performing an encryption or decryption
* operation, that is, regardless of the \p mode parameter. This is
* because CFB mode uses the same key schedule for encryption and
* decryption.
* *
* \note Upon exit, the content of the IV is updated so that you can * \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following * call the same function again on the next
* block(s) of data and get the same result as if it was * block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage. * encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the * If you need to retain the contents of the
* IV, you should either save it manually or use the cipher * IV, you must either save it manually or use the cipher
* module instead. * module instead.
* *
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
* *
* \return 0 if successful * \param ctx The AES context to use for encryption or decryption.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of the input data.
* \param iv_off The offset in IV (updated after use).
* \param iv The initialization vector (updated after use).
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
*
* \return \c 0 on success.
*/ */
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
int mode, int mode,
@ -189,28 +249,36 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
unsigned char *output ); unsigned char *output );
/** /**
* \brief AES-CFB8 buffer encryption/decryption. * \brief This function performs an AES-CFB8 encryption or decryption
* operation.
* *
* Note: Due to the nature of CFB you should use the same key schedule for * It performs the operation defined in the \p mode
* both encryption and decryption. So a context initialized with * parameter (encrypt/decrypt), on the input data buffer defined
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. * in the \p input parameter.
*
* Due to the nature of CFB, you must use the same key schedule for
* both encryption and decryption operations. Therefore, you must
* use the context initialized with mbedtls_aes_setkey_enc() for
* both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
* *
* \note Upon exit, the content of the IV is updated so that you can * \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following * call the same function again on the next
* block(s) of data and get the same result as if it was * block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage. * encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the * If you need to retain the contents of the
* IV, you should either save it manually or use the cipher * IV, you should either save it manually or use the cipher
* module instead. * module instead.
* *
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
* *
* \return 0 if successful * \param ctx The AES context to use for encryption or decryption.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT
* \param length The length of the input data.
* \param iv The initialization vector (updated after use).
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
*
* \return \c 0 on success.
*/ */
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
int mode, int mode,
@ -222,26 +290,32 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CTR) #if defined(MBEDTLS_CIPHER_MODE_CTR)
/** /**
* \brief AES-CTR buffer encryption/decryption * \brief This function performs an AES-CTR encryption or decryption
* operation.
* *
* Warning: You have to keep the maximum use of your counter in mind! * This function performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer
* defined in the \p input parameter.
* *
* Note: Due to the nature of CTR you should use the same key schedule for * Due to the nature of CTR, you must use the same key schedule
* both encryption and decryption. So a context initialized with * for both encryption and decryption operations. Therefore, you
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. * must use the context initialized with mbedtls_aes_setkey_enc()
* for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
* *
* \param ctx AES context * \warning You must keep the maximum use of your counter in mind.
* \param length The length of the data *
* \param nc_off The offset in the current stream_block (for resuming * \param ctx The AES context to use for encryption or decryption.
* within current cipher stream). The offset pointer to * \param length The length of the input data.
* should be 0 at the start of a stream. * \param nc_off The offset in the current \p stream_block, for
* resuming within the current cipher stream. The
* offset pointer should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter. * \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten * \param stream_block The saved stream block for resuming. This is
* by the function. * overwritten by the function.
* \param input The input data stream * \param input The buffer holding the input data.
* \param output The output data stream * \param output The buffer holding the output data.
* *
* \return 0 if successful * \return \c 0 on success.
*/ */
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
size_t length, size_t length,
@ -253,30 +327,30 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
#endif /* MBEDTLS_CIPHER_MODE_CTR */ #endif /* MBEDTLS_CIPHER_MODE_CTR */
/** /**
* \brief Internal AES block encryption function * \brief Internal AES block encryption function. This is only
* (Only exposed to allow overriding it, * exposed to allow overriding it using
* see MBEDTLS_AES_ENCRYPT_ALT) * \c MBEDTLS_AES_ENCRYPT_ALT.
* *
* \param ctx AES context * \param ctx The AES context to use for encryption.
* \param input Plaintext block * \param input The plaintext block.
* \param output Output (ciphertext) block * \param output The output (ciphertext) block.
* *
* \return 0 if successful * \return \c 0 on success.
*/ */
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16], const unsigned char input[16],
unsigned char output[16] ); unsigned char output[16] );
/** /**
* \brief Internal AES block decryption function * \brief Internal AES block decryption function. This is only
* (Only exposed to allow overriding it, * exposed to allow overriding it using see
* see MBEDTLS_AES_DECRYPT_ALT) * \c MBEDTLS_AES_DECRYPT_ALT.
* *
* \param ctx AES context * \param ctx The AES context to use for decryption.
* \param input Ciphertext block * \param input The ciphertext block.
* \param output Output (plaintext) block * \param output The output (plaintext) block.
* *
* \return 0 if successful * \return \c 0 on success.
*/ */
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16], const unsigned char input[16],
@ -292,11 +366,11 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
* \brief Deprecated internal AES block encryption function * \brief Deprecated internal AES block encryption function
* without return value. * without return value.
* *
* \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0 * \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0.
* *
* \param ctx AES context * \param ctx The AES context to use for encryption.
* \param input Plaintext block * \param input Plaintext block.
* \param output Output (ciphertext) block * \param output Output (ciphertext) block.
*/ */
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16], const unsigned char input[16],
@ -306,11 +380,11 @@ MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
* \brief Deprecated internal AES block decryption function * \brief Deprecated internal AES block decryption function
* without return value. * without return value.
* *
* \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0 * \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0.
* *
* \param ctx AES context * \param ctx The AES context to use for decryption.
* \param input Ciphertext block * \param input Ciphertext block.
* \param output Output (plaintext) block * \param output Output (plaintext) block.
*/ */
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16], const unsigned char input[16],
@ -332,9 +406,9 @@ extern "C" {
#endif #endif
/** /**
* \brief Checkup routine * \brief Checkup routine.
* *
* \return 0 if successful, or 1 if the test failed * \return \c 0 on success, or \c 1 on failure.
*/ */
int mbedtls_aes_self_test( int verbose ); int mbedtls_aes_self_test( int verbose );

View file

@ -2,7 +2,8 @@
* \file aesni.h * \file aesni.h
* *
* \brief AES-NI for hardware AES acceleration on some Intel processors * \brief AES-NI for hardware AES acceleration on some Intel processors
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -3,6 +3,10 @@
* *
* \brief The ARCFOUR stream cipher * \brief The ARCFOUR stream cipher
* *
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers instead.
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -21,6 +25,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*
*/ */
#ifndef MBEDTLS_ARC4_H #ifndef MBEDTLS_ARC4_H
#define MBEDTLS_ARC4_H #define MBEDTLS_ARC4_H
@ -33,6 +38,8 @@
#include <stddef.h> #include <stddef.h>
#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED -0x0019 /**< ARC4 hardware accelerator failed. */
#if !defined(MBEDTLS_ARC4_ALT) #if !defined(MBEDTLS_ARC4_ALT)
// Regular implementation // Regular implementation
// //
@ -43,6 +50,10 @@ extern "C" {
/** /**
* \brief ARC4 context structure * \brief ARC4 context structure
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers instead.
*
*/ */
typedef struct typedef struct
{ {
@ -56,6 +67,11 @@ mbedtls_arc4_context;
* \brief Initialize ARC4 context * \brief Initialize ARC4 context
* *
* \param ctx ARC4 context to be initialized * \param ctx ARC4 context to be initialized
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/ */
void mbedtls_arc4_init( mbedtls_arc4_context *ctx ); void mbedtls_arc4_init( mbedtls_arc4_context *ctx );
@ -63,6 +79,11 @@ void mbedtls_arc4_init( mbedtls_arc4_context *ctx );
* \brief Clear ARC4 context * \brief Clear ARC4 context
* *
* \param ctx ARC4 context to be cleared * \param ctx ARC4 context to be cleared
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/ */
void mbedtls_arc4_free( mbedtls_arc4_context *ctx ); void mbedtls_arc4_free( mbedtls_arc4_context *ctx );
@ -72,6 +93,11 @@ void mbedtls_arc4_free( mbedtls_arc4_context *ctx );
* \param ctx ARC4 context to be setup * \param ctx ARC4 context to be setup
* \param key the secret key * \param key the secret key
* \param keylen length of the key, in bytes * \param keylen length of the key, in bytes
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/ */
void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
unsigned int keylen ); unsigned int keylen );
@ -85,6 +111,11 @@ void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
* \param output buffer for the output data * \param output buffer for the output data
* *
* \return 0 if successful * \return 0 if successful
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/ */
int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
unsigned char *output ); unsigned char *output );
@ -105,6 +136,11 @@ extern "C" {
* \brief Checkup routine * \brief Checkup routine
* *
* \return 0 if successful, or 1 if the test failed * \return 0 if successful, or 1 if the test failed
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/ */
int mbedtls_arc4_self_test( int verbose ); int mbedtls_arc4_self_test( int verbose );

View file

@ -2,7 +2,8 @@
* \file asn1.h * \file asn1.h
* *
* \brief Generic ASN.1 parsing * \brief Generic ASN.1 parsing
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -61,7 +62,7 @@
/** /**
* \name DER constants * \name DER constants
* These constants comply with DER encoded the ANS1 type tags. * These constants comply with the DER encoded ASN.1 type tags.
* DER encoding uses hexadecimal representation. * DER encoding uses hexadecimal representation.
* An example DER sequence is:\n * An example DER sequence is:\n
* - 0x02 -- tag indicating INTEGER * - 0x02 -- tag indicating INTEGER
@ -89,6 +90,21 @@
#define MBEDTLS_ASN1_PRIMITIVE 0x00 #define MBEDTLS_ASN1_PRIMITIVE 0x00
#define MBEDTLS_ASN1_CONSTRUCTED 0x20 #define MBEDTLS_ASN1_CONSTRUCTED 0x20
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 #define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
/*
* Bit masks for each of the components of an ASN.1 tag as specified in
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
* paragraph 8.1.2.2:
*
* Bit 8 7 6 5 1
* +-------+-----+------------+
* | Class | P/C | Tag number |
* +-------+-----+------------+
*/
#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0
#define MBEDTLS_ASN1_TAG_PC_MASK 0x20
#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F
/* \} name */ /* \} name */
/* \} addtogroup asn1_module */ /* \} addtogroup asn1_module */

View file

@ -2,7 +2,8 @@
* \file asn1write.h * \file asn1write.h
* *
* \brief ASN.1 buffer writing functionality * \brief ASN.1 buffer writing functionality
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -2,7 +2,8 @@
* \file base64.h * \file base64.h
* *
* \brief RFC 1521 base64 encoding/decoding * \brief RFC 1521 base64 encoding/decoding
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -2,7 +2,8 @@
* \file bignum.h * \file bignum.h
* *
* \brief Multi-precision integer library * \brief Multi-precision integer library
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -72,7 +73,7 @@
* Maximum size of MPIs allowed in bits and bytes for user-MPIs. * Maximum size of MPIs allowed in bits and bytes for user-MPIs.
* ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
* *
* Note: Calculations can results temporarily in larger MPIs. So the number * Note: Calculations can temporarily result in larger MPIs. So the number
* of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher. * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher.
*/ */
#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ #define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
@ -685,6 +686,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
* *
* \return 0 if successful, * \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*
* \note The bytes obtained from the PRNG are interpreted
* as a big-endian representation of an MPI; this can
* be relevant in applications like deterministic ECDSA.
*/ */
int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),

View file

@ -2,7 +2,8 @@
* \file blowfish.h * \file blowfish.h
* *
* \brief Blowfish block cipher * \brief Blowfish block cipher
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -42,6 +43,7 @@
#define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */ #define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */
#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */ #define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */
#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */
#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */ #define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
#if !defined(MBEDTLS_BLOWFISH_ALT) #if !defined(MBEDTLS_BLOWFISH_ALT)

View file

@ -2,7 +2,8 @@
* \file bn_mul.h * \file bn_mul.h
* *
* \brief Multi-precision integer library * \brief Multi-precision integer library
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -50,7 +51,14 @@
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(__GNUC__) && \ #if defined(__GNUC__) && \
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
#if defined(__i386__)
/*
* Disable use of the i386 assembly code below if option -O0, to disable all
* compiler optimisations, is passed, detected with __OPTIMIZE__
* This is done as the number of registers used in the assembly code doesn't
* work with the -O0 option.
*/
#if defined(__i386__) && defined(__OPTIMIZE__)
#define MULADDC_INIT \ #define MULADDC_INIT \
asm( \ asm( \
@ -143,7 +151,7 @@
"movl %%esi, %3 \n\t" \ "movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \ : "eax", "ebx", "ecx", "edx", "esi", "edi" \
); );
#else #else
@ -155,7 +163,7 @@
"movl %%esi, %3 \n\t" \ "movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \ : "eax", "ebx", "ecx", "edx", "esi", "edi" \
); );
#endif /* SSE2 */ #endif /* SSE2 */
#endif /* i386 */ #endif /* i386 */
@ -522,7 +530,7 @@
"swi r3, %2 \n\t" \ "swi r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \ : "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \ : "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4" "r5", "r6", "r7", "r8", \ : "r3", "r4", "r5", "r6", "r7", "r8", \
"r9", "r10", "r11", "r12", "r13" \ "r9", "r10", "r11", "r12", "r13" \
); );

View file

@ -2,7 +2,8 @@
* \file camellia.h * \file camellia.h
* *
* \brief Camellia block cipher * \brief Camellia block cipher
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -39,6 +40,7 @@
#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */ #define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */
#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */ #define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */
#if !defined(MBEDTLS_CAMELLIA_ALT) #if !defined(MBEDTLS_CAMELLIA_ALT)
// Regular implementation // Regular implementation

View file

@ -1,9 +1,19 @@
/** /**
* \file ccm.h * \file ccm.h
* *
* \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers * \brief CCM combines Counter mode encryption with CBC-MAC authentication
* for 128-bit block ciphers.
* *
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Input to CCM includes the following elements:
* <ul><li>Payload - data that is both authenticated and encrypted.</li>
* <li>Associated data (Adata) - data that is authenticated but not
* encrypted, For example, a header.</li>
* <li>Nonce - A unique value that is assigned to the payload and the
* associated data.</li></ul>
*
*/
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,46 +30,54 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_CCM_H #ifndef MBEDTLS_CCM_H
#define MBEDTLS_CCM_H #define MBEDTLS_CCM_H
#include "cipher.h" #include "cipher.h"
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to function. */ #define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */
#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ #define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */
#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
#if !defined(MBEDTLS_CCM_ALT)
// Regular implementation
//
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** /**
* \brief CCM context structure * \brief The CCM context-type definition. The CCM context is passed
* to the APIs called.
*/ */
typedef struct { typedef struct {
mbedtls_cipher_context_t cipher_ctx; /*!< cipher context used */ mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
} }
mbedtls_ccm_context; mbedtls_ccm_context;
/** /**
* \brief Initialize CCM context (just makes references valid) * \brief This function initializes the specified CCM context,
* Makes the context ready for mbedtls_ccm_setkey() or * to make references valid, and prepare the context
* mbedtls_ccm_free(). * for mbedtls_ccm_setkey() or mbedtls_ccm_free().
* *
* \param ctx CCM context to initialize * \param ctx The CCM context to initialize.
*/ */
void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
/** /**
* \brief CCM initialization (encryption and decryption) * \brief This function initializes the CCM context set in the
* \p ctx parameter and sets the encryption key.
* *
* \param ctx CCM context to be initialized * \param ctx The CCM context to initialize.
* \param cipher cipher to use (a 128-bit block cipher) * \param cipher The 128-bit block cipher to use.
* \param key encryption key * \param key The encryption key.
* \param keybits key size in bits (must be acceptable by the cipher) * \param keybits The key size in bits. This must be acceptable by the cipher.
* *
* \return 0 if successful, or a cipher specific error code * \return \c 0 on success, or a cipher-specific error code.
*/ */
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
mbedtls_cipher_id_t cipher, mbedtls_cipher_id_t cipher,
@ -67,36 +85,37 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
unsigned int keybits ); unsigned int keybits );
/** /**
* \brief Free a CCM context and underlying cipher sub-context * \brief This function releases and clears the specified CCM context
* and underlying cipher sub-context.
* *
* \param ctx CCM context to free * \param ctx The CCM context to clear.
*/ */
void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
/** /**
* \brief CCM buffer encryption * \brief This function encrypts a buffer using CCM.
* *
* \param ctx CCM context * \param ctx The CCM context to use for encryption.
* \param length length of the input data in bytes * \param length The length of the input data in Bytes.
* \param iv nonce (initialization vector) * \param iv Initialization vector (nonce).
* \param iv_len length of IV in bytes * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
* must be 2, 3, 4, 5, 6, 7 or 8 * \param add The additional data field.
* \param add additional data * \param add_len The length of additional data in Bytes.
* \param add_len length of additional data in bytes * Must be less than 2^16 - 2^8.
* must be less than 2^16 - 2^8 * \param input The buffer holding the input data.
* \param input buffer holding the input data * \param output The buffer holding the output data.
* \param output buffer for holding the output data * Must be at least \p length Bytes wide.
* must be at least 'length' bytes wide * \param tag The buffer holding the tag.
* \param tag buffer for holding the tag * \param tag_len The length of the tag to generate in Bytes:
* \param tag_len length of the tag to generate in bytes * 4, 6, 8, 10, 12, 14 or 16.
* must be 4, 6, 8, 10, 14 or 16
* *
* \note The tag is written to a separate buffer. To get the tag * \note The tag is written to a separate buffer. To concatenate
* concatenated with the output as in the CCM spec, use * the \p tag with the \p output, as done in <em>RFC-3610:
* tag = output + length and make sure the output buffer is * Counter with CBC-MAC (CCM)</em>, use
* at least length + tag_len wide. * \p tag = \p output + \p length, and make sure that the
* output buffer is at least \p length + \p tag_len wide.
* *
* \return 0 if successful * \return \c 0 on success.
*/ */
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len, const unsigned char *iv, size_t iv_len,
@ -105,21 +124,25 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
unsigned char *tag, size_t tag_len ); unsigned char *tag, size_t tag_len );
/** /**
* \brief CCM buffer authenticated decryption * \brief This function performs a CCM authenticated decryption of a
* buffer.
* *
* \param ctx CCM context * \param ctx The CCM context to use for decryption.
* \param length length of the input data * \param length The length of the input data in Bytes.
* \param iv initialization vector * \param iv Initialization vector.
* \param iv_len length of IV * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
* \param add additional data * \param add The additional data field.
* \param add_len length of additional data * \param add_len The length of additional data in Bytes.
* \param input buffer holding the input data * Must be less than 2^16 - 2^8.
* \param output buffer for holding the output data * \param input The buffer holding the input data.
* \param tag buffer holding the tag * \param output The buffer holding the output data.
* \param tag_len length of the tag * Must be at least \p length Bytes wide.
* \param tag The buffer holding the tag.
* \param tag_len The length of the tag in Bytes.
* 4, 6, 8, 10, 12, 14 or 16.
* *
* \return 0 if successful and authenticated, * \return 0 if successful and authenticated, or
* MBEDTLS_ERR_CCM_AUTH_FAILED if tag does not match * #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
*/ */
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len, const unsigned char *iv, size_t iv_len,
@ -127,11 +150,23 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *input, unsigned char *output, const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len ); const unsigned char *tag, size_t tag_len );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_CCM_ALT */
#include "ccm_alt.h"
#endif /* MBEDTLS_CCM_ALT */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/** /**
* \brief Checkup routine * \brief The CCM checkup routine.
* *
* \return 0 if successful, or 1 if the test failed * \return \c 0 on success, or \c 1 on failure.
*/ */
int mbedtls_ccm_self_test( int verbose ); int mbedtls_ccm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */

View file

@ -2,7 +2,8 @@
* \file certs.h * \file certs.h
* *
* \brief Sample certificates and DHM parameters for testing * \brief Sample certificates and DHM parameters for testing
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -2,7 +2,8 @@
* \file check_config.h * \file check_config.h
* *
* \brief Consistency checks for configuration options * \brief Consistency checks for configuration options
* */
/*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -79,6 +80,10 @@
#error "MBEDTLS_DHM_C defined, but not all prerequisites" #error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC)
#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CMAC_C) && \ #if defined(MBEDTLS_CMAC_C) && \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
#error "MBEDTLS_CMAC_C defined, but not all prerequisites" #error "MBEDTLS_CMAC_C defined, but not all prerequisites"

View file

@ -1,11 +1,12 @@
/** /**
* \file cipher.h * \file cipher.h
* *
* \brief Generic cipher wrapper. * \brief The generic cipher wrapper.
* *
* \author Adriaan de Jong <dejong@fox-it.com> * \author Adriaan de Jong <dejong@fox-it.com>
* */
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved /*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -22,7 +23,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_CIPHER_H #ifndef MBEDTLS_CIPHER_H
@ -44,7 +45,7 @@
#define MBEDTLS_CIPHER_MODE_WITH_PADDING #define MBEDTLS_CIPHER_MODE_WITH_PADDING
#endif #endif
#if defined(MBEDTLS_ARC4_C) #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
#define MBEDTLS_CIPHER_MODE_STREAM #define MBEDTLS_CIPHER_MODE_STREAM
#endif #endif
@ -54,20 +55,28 @@
#endif #endif
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ #define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */ #define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */
#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ #define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ #define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ #define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ #define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid, eg because it was free()ed. */ #define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */
#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */ #define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */ #define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/**
* \brief An enumeration of supported ciphers.
*
* \warning ARC4 and DES are considered weak ciphers and their use
* constitutes a security risk. We recommend considering stronger
* ciphers instead.
*/
typedef enum { typedef enum {
MBEDTLS_CIPHER_ID_NONE = 0, MBEDTLS_CIPHER_ID_NONE = 0,
MBEDTLS_CIPHER_ID_NULL, MBEDTLS_CIPHER_ID_NULL,
@ -79,6 +88,13 @@ typedef enum {
MBEDTLS_CIPHER_ID_ARC4, MBEDTLS_CIPHER_ID_ARC4,
} mbedtls_cipher_id_t; } mbedtls_cipher_id_t;
/**
* \brief An enumeration of supported (cipher, mode) pairs.
*
* \warning ARC4 and DES are considered weak ciphers and their use
* constitutes a security risk. We recommend considering stronger
* ciphers instead.
*/
typedef enum { typedef enum {
MBEDTLS_CIPHER_NONE = 0, MBEDTLS_CIPHER_NONE = 0,
MBEDTLS_CIPHER_NULL, MBEDTLS_CIPHER_NULL,
@ -131,6 +147,7 @@ typedef enum {
MBEDTLS_CIPHER_CAMELLIA_256_CCM, MBEDTLS_CIPHER_CAMELLIA_256_CCM,
} mbedtls_cipher_type_t; } mbedtls_cipher_type_t;
/** Supported cipher modes. */
typedef enum { typedef enum {
MBEDTLS_MODE_NONE = 0, MBEDTLS_MODE_NONE = 0,
MBEDTLS_MODE_ECB, MBEDTLS_MODE_ECB,
@ -143,14 +160,16 @@ typedef enum {
MBEDTLS_MODE_CCM, MBEDTLS_MODE_CCM,
} mbedtls_cipher_mode_t; } mbedtls_cipher_mode_t;
/** Supported cipher padding types. */
typedef enum { typedef enum {
MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default) */ MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */
MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding */ MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */
MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding */ MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */
MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible!) */ MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible). */
MBEDTLS_PADDING_NONE, /**< never pad (full blocks only) */ MBEDTLS_PADDING_NONE, /**< never pad (full blocks only). */
} mbedtls_cipher_padding_t; } mbedtls_cipher_padding_t;
/** Type of operation. */
typedef enum { typedef enum {
MBEDTLS_OPERATION_NONE = -1, MBEDTLS_OPERATION_NONE = -1,
MBEDTLS_DECRYPT = 0, MBEDTLS_DECRYPT = 0,
@ -158,19 +177,19 @@ typedef enum {
} mbedtls_operation_t; } mbedtls_operation_t;
enum { enum {
/** Undefined key length */ /** Undefined key length. */
MBEDTLS_KEY_LENGTH_NONE = 0, MBEDTLS_KEY_LENGTH_NONE = 0,
/** Key length, in bits (including parity), for DES keys */ /** Key length, in bits (including parity), for DES keys. */
MBEDTLS_KEY_LENGTH_DES = 64, MBEDTLS_KEY_LENGTH_DES = 64,
/** Key length, in bits (including parity), for DES in two key EDE */ /** Key length in bits, including parity, for DES in two-key EDE. */
MBEDTLS_KEY_LENGTH_DES_EDE = 128, MBEDTLS_KEY_LENGTH_DES_EDE = 128,
/** Key length, in bits (including parity), for DES in three-key EDE */ /** Key length in bits, including parity, for DES in three-key EDE. */
MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
}; };
/** Maximum length of any IV, in bytes */ /** Maximum length of any IV, in Bytes. */
#define MBEDTLS_MAX_IV_LENGTH 16 #define MBEDTLS_MAX_IV_LENGTH 16
/** Maximum block size of any cipher, in bytes */ /** Maximum block size of any cipher, in Bytes. */
#define MBEDTLS_MAX_BLOCK_LENGTH 16 #define MBEDTLS_MAX_BLOCK_LENGTH 16
/** /**
@ -184,33 +203,40 @@ typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
/** /**
* Cipher information. Allows cipher functions to be called in a generic way. * Cipher information. Allows calling cipher functions
* in a generic way.
*/ */
typedef struct { typedef struct {
/** Full cipher identifier (e.g. MBEDTLS_CIPHER_AES_256_CBC) */ /** Full cipher identifier. For example,
* MBEDTLS_CIPHER_AES_256_CBC.
*/
mbedtls_cipher_type_t type; mbedtls_cipher_type_t type;
/** Cipher mode (e.g. MBEDTLS_MODE_CBC) */ /** The cipher mode. For example, MBEDTLS_MODE_CBC. */
mbedtls_cipher_mode_t mode; mbedtls_cipher_mode_t mode;
/** Cipher key length, in bits (default length for variable sized ciphers) /** The cipher key length, in bits. This is the
* (Includes parity bits for ciphers like DES) */ * default length for variable sized ciphers.
* Includes parity bits for ciphers like DES.
*/
unsigned int key_bitlen; unsigned int key_bitlen;
/** Name of the cipher */ /** Name of the cipher. */
const char * name; const char * name;
/** IV/NONCE size, in bytes. /** IV or nonce size, in Bytes.
* For cipher that accept many sizes: recommended size */ * For ciphers that accept variable IV sizes,
* this is the recommended size.
*/
unsigned int iv_size; unsigned int iv_size;
/** Flags for variable IV size, variable key size, etc. */ /** Flags to set. For example, if the cipher supports variable IV sizes or variable key sizes. */
int flags; int flags;
/** block size, in bytes */ /** The block size, in Bytes. */
unsigned int block_size; unsigned int block_size;
/** Base cipher information and functions */ /** Struct for base cipher information and functions. */
const mbedtls_cipher_base_t *base; const mbedtls_cipher_base_t *base;
} mbedtls_cipher_info_t; } mbedtls_cipher_info_t;
@ -219,125 +245,133 @@ typedef struct {
* Generic cipher context. * Generic cipher context.
*/ */
typedef struct { typedef struct {
/** Information about the associated cipher */ /** Information about the associated cipher. */
const mbedtls_cipher_info_t *cipher_info; const mbedtls_cipher_info_t *cipher_info;
/** Key length to use */ /** Key length to use. */
int key_bitlen; int key_bitlen;
/** Operation that the context's key has been initialised for */ /** Operation that the key of the context has been
* initialized for.
*/
mbedtls_operation_t operation; mbedtls_operation_t operation;
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/** Padding functions to use, if relevant for cipher mode */ /** Padding functions to use, if relevant for
* the specific cipher mode.
*/
void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
#endif #endif
/** Buffer for data that hasn't been encrypted yet */ /** Buffer for input that has not been processed yet. */
unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
/** Number of bytes that still need processing */ /** Number of Bytes that have not been processed yet. */
size_t unprocessed_len; size_t unprocessed_len;
/** Current IV or NONCE_COUNTER for CTR-mode */ /** Current IV or NONCE_COUNTER for CTR-mode. */
unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
/** IV size in bytes (for ciphers with variable-length IVs) */ /** IV size in Bytes, for ciphers with variable-length IVs. */
size_t iv_size; size_t iv_size;
/** Cipher-specific context */ /** The cipher-specific context. */
void *cipher_ctx; void *cipher_ctx;
#if defined(MBEDTLS_CMAC_C) #if defined(MBEDTLS_CMAC_C)
/** CMAC Specific context */ /** CMAC-specific context. */
mbedtls_cmac_context_t *cmac_ctx; mbedtls_cmac_context_t *cmac_ctx;
#endif #endif
} mbedtls_cipher_context_t; } mbedtls_cipher_context_t;
/** /**
* \brief Returns the list of ciphers supported by the generic cipher module. * \brief This function retrieves the list of ciphers supported by the generic
* cipher module.
* *
* \return a statically allocated array of ciphers, the last entry * \return A statically-allocated array of ciphers. The last entry
* is 0. * is zero.
*/ */
const int *mbedtls_cipher_list( void ); const int *mbedtls_cipher_list( void );
/** /**
* \brief Returns the cipher information structure associated * \brief This function retrieves the cipher-information
* with the given cipher name. * structure associated with the given cipher name.
* *
* \param cipher_name Name of the cipher to search for. * \param cipher_name Name of the cipher to search for.
* *
* \return the cipher information structure associated with the * \return The cipher information structure associated with the
* given cipher_name, or NULL if not found. * given \p cipher_name, or NULL if not found.
*/ */
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
/** /**
* \brief Returns the cipher information structure associated * \brief This function retrieves the cipher-information
* with the given cipher type. * structure associated with the given cipher type.
* *
* \param cipher_type Type of the cipher to search for. * \param cipher_type Type of the cipher to search for.
* *
* \return the cipher information structure associated with the * \return The cipher information structure associated with the
* given cipher_type, or NULL if not found. * given \p cipher_type, or NULL if not found.
*/ */
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
/** /**
* \brief Returns the cipher information structure associated * \brief This function retrieves the cipher-information
* with the given cipher id, key size and mode. * structure associated with the given cipher ID,
* key size and mode.
* *
* \param cipher_id Id of the cipher to search for * \param cipher_id The ID of the cipher to search for. For example,
* (e.g. MBEDTLS_CIPHER_ID_AES) * #MBEDTLS_CIPHER_ID_AES.
* \param key_bitlen Length of the key in bits * \param key_bitlen The length of the key in bits.
* \param mode Cipher mode (e.g. MBEDTLS_MODE_CBC) * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC.
* *
* \return the cipher information structure associated with the * \return The cipher information structure associated with the
* given cipher_type, or NULL if not found. * given \p cipher_id, or NULL if not found.
*/ */
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
int key_bitlen, int key_bitlen,
const mbedtls_cipher_mode_t mode ); const mbedtls_cipher_mode_t mode );
/** /**
* \brief Initialize a cipher_context (as NONE) * \brief This function initializes a \p cipher_context as NONE.
*/ */
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
/** /**
* \brief Free and clear the cipher-specific context of ctx. * \brief This function frees and clears the cipher-specific
* Freeing ctx itself remains the responsibility of the * context of \p ctx. Freeing \p ctx itself remains the
* caller. * responsibility of the caller.
*/ */
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
/** /**
* \brief Initialises and fills the cipher context structure with * \brief This function initializes and fills the cipher-context
* the appropriate values. * structure with the appropriate values. It also clears
* the structure.
* *
* \note Currently also clears structure. In future versions you * \param ctx The context to initialize. May not be NULL.
* will be required to call mbedtls_cipher_init() on the structure * \param cipher_info The cipher to use.
* first.
* *
* \param ctx context to initialise. May not be NULL. * \return \c 0 on success,
* \param cipher_info cipher to use. * #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
* * #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
* \return 0 on success,
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
* MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
* cipher-specific context failed. * cipher-specific context failed.
*
* \internal Currently, the function also clears the structure.
* In future versions, the caller will be required to call
* mbedtls_cipher_init() on the structure first.
*/ */
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ); int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info );
/** /**
* \brief Returns the block size of the given cipher. * \brief This function returns the block size of the given cipher.
* *
* \param ctx cipher's context. Must have been initialised. * \param ctx The context of the cipher. Must be initialized.
* *
* \return size of the cipher's blocks, or 0 if ctx has not been * \return The size of the blocks of the cipher, or zero if \p ctx
* initialised. * has not been initialized.
*/ */
static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx ) static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx )
{ {
@ -348,13 +382,13 @@ static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_c
} }
/** /**
* \brief Returns the mode of operation for the cipher. * \brief This function returns the mode of operation for
* (e.g. MBEDTLS_MODE_CBC) * the cipher. For example, MBEDTLS_MODE_CBC.
* *
* \param ctx cipher's context. Must have been initialised. * \param ctx The context of the cipher. Must be initialized.
* *
* \return mode of operation, or MBEDTLS_MODE_NONE if ctx * \return The mode of operation, or #MBEDTLS_MODE_NONE if
* has not been initialised. * \p ctx has not been initialized.
*/ */
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx ) static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx )
{ {
@ -365,13 +399,14 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtl
} }
/** /**
* \brief Returns the size of the cipher's IV/NONCE in bytes. * \brief This function returns the size of the IV or nonce
* of the cipher, in Bytes.
* *
* \param ctx cipher's context. Must have been initialised. * \param ctx The context of the cipher. Must be initialized.
* *
* \return If IV has not been set yet: (recommended) IV size * \return <ul><li>If no IV has been set: the recommended IV size.
* (0 for ciphers not using IV/NONCE). * 0 for ciphers not using IV or nonce.</li>
* If IV has already been set: actual size. * <li>If IV has already been set: the actual size.</li></ul>
*/ */
static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx ) static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx )
{ {
@ -385,12 +420,12 @@ static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ct
} }
/** /**
* \brief Returns the type of the given cipher. * \brief This function returns the type of the given cipher.
* *
* \param ctx cipher's context. Must have been initialised. * \param ctx The context of the cipher. Must be initialized.
* *
* \return type of the cipher, or MBEDTLS_CIPHER_NONE if ctx has * \return The type of the cipher, or #MBEDTLS_CIPHER_NONE if
* not been initialised. * \p ctx has not been initialized.
*/ */
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx ) static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx )
{ {
@ -401,11 +436,13 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_ciphe
} }
/** /**
* \brief Returns the name of the given cipher, as a string. * \brief This function returns the name of the given cipher
* as a string.
* *
* \param ctx cipher's context. Must have been initialised. * \param ctx The context of the cipher. Must be initialized.
* *
* \return name of the cipher, or NULL if ctx was not initialised. * \return The name of the cipher, or NULL if \p ctx has not
* been not initialized.
*/ */
static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx ) static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx )
{ {
@ -416,13 +453,13 @@ static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_
} }
/** /**
* \brief Returns the key length of the cipher. * \brief This function returns the key length of the cipher.
* *
* \param ctx cipher's context. Must have been initialised. * \param ctx The context of the cipher. Must be initialized.
* *
* \return cipher's key length, in bits, or * \return The key length of the cipher in bits, or
* MBEDTLS_KEY_LENGTH_NONE if ctx has not been * #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
* initialised. * initialized.
*/ */
static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx ) static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx )
{ {
@ -433,13 +470,13 @@ static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t
} }
/** /**
* \brief Returns the operation of the given cipher. * \brief This function returns the operation of the given cipher.
* *
* \param ctx cipher's context. Must have been initialised. * \param ctx The context of the cipher. Must be initialized.
* *
* \return operation (MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT), * \return The type of operation: #MBEDTLS_ENCRYPT or
* or MBEDTLS_OPERATION_NONE if ctx has not been * #MBEDTLS_DECRYPT, or #MBEDTLS_OPERATION_NONE if \p ctx
* initialised. * has not been initialized.
*/ */
static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx ) static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx )
{ {
@ -450,18 +487,18 @@ static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_ci
} }
/** /**
* \brief Set the key to use with the given context. * \brief This function sets the key to use with the given context.
* *
* \param ctx generic cipher context. May not be NULL. Must have been * \param ctx The generic cipher context. May not be NULL. Must have
* initialised using cipher_context_from_type or * been initialized using mbedtls_cipher_info_from_type()
* cipher_context_from_string. * or mbedtls_cipher_info_from_string().
* \param key The key to use. * \param key The key to use.
* \param key_bitlen key length to use, in bits. * \param key_bitlen The key length to use, in bits.
* \param operation Operation that the key will be used for, either * \param operation The operation that the key will be used for:
* MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT. * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
* *
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if * \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails or a cipher specific * parameter verification fails, or a cipher-specific
* error code. * error code.
*/ */
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
@ -469,170 +506,176 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *k
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/** /**
* \brief Set padding mode, for cipher modes that use padding. * \brief This function sets the padding mode, for cipher modes
* (Default: PKCS7 padding.) * that use padding.
* *
* \param ctx generic cipher context * The default passing mode is PKCS7 padding.
* \param mode padding mode
* *
* \returns 0 on success, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE * \param ctx The generic cipher context.
* if selected padding mode is not supported, or * \param mode The padding mode.
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode *
* \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
* if the selected padding mode is not supported, or
* #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
* does not support padding. * does not support padding.
*/ */
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ); int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode );
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
/** /**
* \brief Set the initialization vector (IV) or nonce * \brief This function sets the initialization vector (IV)
* or nonce.
* *
* \param ctx generic cipher context * \param ctx The generic cipher context.
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* \param iv_len IV length for ciphers with variable-size IV; * \param iv_len The IV length for ciphers with variable-size IV.
* discarded by ciphers with fixed-size IV. * This parameter is discarded by ciphers with fixed-size IV.
* *
* \returns 0 on success, or MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA * \returns \c 0 on success, or #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
* *
* \note Some ciphers don't use IVs nor NONCE. For these * \note Some ciphers do not use IVs nor nonce. For these
* ciphers, this function has no effect. * ciphers, this function has no effect.
*/ */
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len ); const unsigned char *iv, size_t iv_len );
/** /**
* \brief Finish preparation of the given context * \brief This function resets the cipher state.
* *
* \param ctx generic cipher context * \param ctx The generic cipher context.
* *
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA * \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
* if parameter verification fails. * if parameter verification fails.
*/ */
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
/** /**
* \brief Add additional data (for AEAD ciphers). * \brief This function adds additional data for AEAD ciphers.
* Currently only supported with GCM. * Only supported with GCM. Must be called
* Must be called exactly once, after mbedtls_cipher_reset(). * exactly once, after mbedtls_cipher_reset().
* *
* \param ctx generic cipher context * \param ctx The generic cipher context.
* \param ad Additional data to use. * \param ad The additional data to use.
* \param ad_len Length of ad. * \param ad_len the Length of \p ad.
* *
* \return 0 on success, or a specific error code. * \return \c 0 on success, or a specific error code on failure.
*/ */
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len ); const unsigned char *ad, size_t ad_len );
#endif /* MBEDTLS_GCM_C */ #endif /* MBEDTLS_GCM_C */
/** /**
* \brief Generic cipher update function. Encrypts/decrypts * \brief The generic cipher update function. It encrypts or
* using the given cipher context. Writes as many block * decrypts using the given cipher context. Writes as
* size'd blocks of data as possible to output. Any data * many block-sized blocks of data as possible to output.
* that cannot be written immediately will either be added * Any data that cannot be written immediately is either
* to the next block, or flushed when cipher_final is * added to the next block, or flushed when
* called. * mbedtls_cipher_finish() is called.
* Exception: for MBEDTLS_MODE_ECB, expects single block * Exception: For MBEDTLS_MODE_ECB, expects a single block
* in size (e.g. 16 bytes for AES) * in size. For example, 16 Bytes for AES.
* *
* \param ctx generic cipher context * \param ctx The generic cipher context.
* \param input buffer holding the input data * \param input The buffer holding the input data.
* \param ilen length of the input data * \param ilen The length of the input data.
* \param output buffer for the output data. Should be able to hold at * \param output The buffer for the output data. Must be able to hold at
* least ilen + block_size. Cannot be the same buffer as * least \p ilen + block_size. Must not be the same buffer
* input! * as input.
* \param olen length of the output data, will be filled with the * \param olen The length of the output data, to be updated with the
* actual number of bytes written. * actual number of Bytes written.
* *
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if * \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails, * parameter verification fails,
* MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an * #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
* unsupported mode for a cipher or a cipher specific * unsupported mode for a cipher, or a cipher-specific
* error code. * error code.
* *
* \note If the underlying cipher is GCM, all calls to this * \note If the underlying cipher is GCM, all calls to this
* function, except the last one before mbedtls_cipher_finish(), * function, except the last one before
* must have ilen a multiple of the block size. * mbedtls_cipher_finish(). Must have \p ilen as a
* multiple of the block_size.
*/ */
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
size_t ilen, unsigned char *output, size_t *olen ); size_t ilen, unsigned char *output, size_t *olen );
/** /**
* \brief Generic cipher finalisation function. If data still * \brief The generic cipher finalization function. If data still
* needs to be flushed from an incomplete block, data * needs to be flushed from an incomplete block, the data
* contained within it will be padded with the size of * contained in it is padded to the size of
* the last block, and written to the output buffer. * the last block, and written to the \p output buffer.
* *
* \param ctx Generic cipher context * \param ctx The generic cipher context.
* \param output buffer to write data to. Needs block_size available. * \param output The buffer to write data to. Needs block_size available.
* \param olen length of the data written to the output buffer. * \param olen The length of the data written to the \p output buffer.
* *
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if * \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails, * parameter verification fails,
* MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption * #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
* expected a full block but was not provided one, * expected a full block but was not provided one,
* MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding * #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting or a cipher specific error code. * while decrypting, or a cipher-specific error code
* on failure for any other reason.
*/ */
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen ); unsigned char *output, size_t *olen );
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
/** /**
* \brief Write tag for AEAD ciphers. * \brief This function writes a tag for AEAD ciphers.
* Currently only supported with GCM. * Only supported with GCM.
* Must be called after mbedtls_cipher_finish(). * Must be called after mbedtls_cipher_finish().
* *
* \param ctx Generic cipher context * \param ctx The generic cipher context.
* \param tag buffer to write the tag * \param tag The buffer to write the tag to.
* \param tag_len Length of the tag to write * \param tag_len The length of the tag to write.
* *
* \return 0 on success, or a specific error code. * \return \c 0 on success, or a specific error code on failure.
*/ */
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len ); unsigned char *tag, size_t tag_len );
/** /**
* \brief Check tag for AEAD ciphers. * \brief This function checks the tag for AEAD ciphers.
* Currently only supported with GCM. * Only supported with GCM.
* Must be called after mbedtls_cipher_finish(). * Must be called after mbedtls_cipher_finish().
* *
* \param ctx Generic cipher context * \param ctx The generic cipher context.
* \param tag Buffer holding the tag * \param tag The buffer holding the tag.
* \param tag_len Length of the tag to check * \param tag_len The length of the tag to check.
* *
* \return 0 on success, or a specific error code. * \return \c 0 on success, or a specific error code on failure.
*/ */
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len ); const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_GCM_C */ #endif /* MBEDTLS_GCM_C */
/** /**
* \brief Generic all-in-one encryption/decryption * \brief The generic all-in-one encryption/decryption function,
* (for all ciphers except AEAD constructs). * for all ciphers except AEAD constructs.
* *
* \param ctx generic cipher context * \param ctx The generic cipher context.
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* \param iv_len IV length for ciphers with variable-size IV; * \param iv_len The IV length for ciphers with variable-size IV.
* discarded by ciphers with fixed-size IV. * This parameter is discarded by ciphers with fixed-size
* \param input buffer holding the input data * IV.
* \param ilen length of the input data * \param input The buffer holding the input data.
* \param output buffer for the output data. Should be able to hold at * \param ilen The length of the input data.
* least ilen + block_size. Cannot be the same buffer as * \param output The buffer for the output data. Must be able to hold at
* input! * least \p ilen + block_size. Must not be the same buffer
* \param olen length of the output data, will be filled with the * as input.
* actual number of bytes written. * \param olen The length of the output data, to be updated with the
* actual number of Bytes written.
* *
* \note Some ciphers don't use IVs nor NONCE. For these * \note Some ciphers do not use IVs nor nonce. For these
* ciphers, use iv = NULL and iv_len = 0. * ciphers, use \p iv = NULL and \p iv_len = 0.
* *
* \returns 0 on success, or * \returns \c 0 on success, or
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or * #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption * #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
* expected a full block but was not provided one, or * expected a full block but was not provided one, or
* MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding * #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting, or * while decrypting, or a cipher-specific error code on
* a cipher specific error code. * failure for any other reason.
*/ */
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len, const unsigned char *iv, size_t iv_len,
@ -641,26 +684,26 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CIPHER_MODE_AEAD) #if defined(MBEDTLS_CIPHER_MODE_AEAD)
/** /**
* \brief Generic autenticated encryption (AEAD ciphers). * \brief The generic autenticated encryption (AEAD) function.
* *
* \param ctx generic cipher context * \param ctx The generic cipher context.
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* \param iv_len IV length for ciphers with variable-size IV; * \param iv_len The IV length for ciphers with variable-size IV.
* discarded by ciphers with fixed-size IV. * This parameter is discarded by ciphers with fixed-size IV.
* \param ad Additional data to authenticate. * \param ad The additional data to authenticate.
* \param ad_len Length of ad. * \param ad_len The length of \p ad.
* \param input buffer holding the input data * \param input The buffer holding the input data.
* \param ilen length of the input data * \param ilen The length of the input data.
* \param output buffer for the output data. * \param output The buffer for the output data.
* Should be able to hold at least ilen. * Must be able to hold at least \p ilen.
* \param olen length of the output data, will be filled with the * \param olen The length of the output data, to be updated with the
* actual number of bytes written. * actual number of Bytes written.
* \param tag buffer for the authentication tag * \param tag The buffer for the authentication tag.
* \param tag_len desired tag length * \param tag_len The desired length of the authentication tag.
* *
* \returns 0 on success, or * \returns \c 0 on success, or
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or * #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* a cipher specific error code. * a cipher-specific error code.
*/ */
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len, const unsigned char *iv, size_t iv_len,
@ -670,31 +713,31 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len ); unsigned char *tag, size_t tag_len );
/** /**
* \brief Generic autenticated decryption (AEAD ciphers). * \brief The generic autenticated decryption (AEAD) function.
* *
* \param ctx generic cipher context * \param ctx The generic cipher context.
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* \param iv_len IV length for ciphers with variable-size IV; * \param iv_len The IV length for ciphers with variable-size IV.
* discarded by ciphers with fixed-size IV. * This parameter is discarded by ciphers with fixed-size IV.
* \param ad Additional data to be authenticated. * \param ad The additional data to be authenticated.
* \param ad_len Length of ad. * \param ad_len The length of \p ad.
* \param input buffer holding the input data * \param input The buffer holding the input data.
* \param ilen length of the input data * \param ilen The length of the input data.
* \param output buffer for the output data. * \param output The buffer for the output data.
* Should be able to hold at least ilen. * Must be able to hold at least \p ilen.
* \param olen length of the output data, will be filled with the * \param olen The length of the output data, to be updated with the
* actual number of bytes written. * actual number of Bytes written.
* \param tag buffer holding the authentication tag * \param tag The buffer holding the authentication tag.
* \param tag_len length of the authentication tag * \param tag_len The length of the authentication tag.
* *
* \returns 0 on success, or * \returns \c 0 on success, or
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or * #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* MBEDTLS_ERR_CIPHER_AUTH_FAILED if data isn't authentic, * #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic,
* or a cipher specific error code. * or a cipher-specific error code on failure for any other reason.
* *
* \note If the data is not authentic, then the output buffer * \note If the data is not authentic, then the output buffer
* is zeroed out to prevent the unauthentic plaintext to * is zeroed out to prevent the unauthentic plaintext being
* be used by mistake, making this interface safer. * used, making this interface safer.
*/ */
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len, const unsigned char *iv, size_t iv_len,

View file

@ -4,7 +4,8 @@
* \brief Cipher wrappers. * \brief Cipher wrappers.
* *
* \author Adriaan de Jong <dejong@fox-it.com> * \author Adriaan de Jong <dejong@fox-it.com>
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -1,10 +1,11 @@
/** /**
* \file cmac.h * \file cmac.h
* *
* \brief Cipher-based Message Authentication Code (CMAC) Mode for * \brief The Cipher-based Message Authentication Code (CMAC) Mode for
* Authentication * Authentication.
* */
* Copyright (C) 2015-2016, ARM Limited, All Rights Reserved /*
* Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -21,117 +22,137 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_CMAC_H #ifndef MBEDTLS_CMAC_H
#define MBEDTLS_CMAC_H #define MBEDTLS_CMAC_H
#include "mbedtls/cipher.h" #include "cipher.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A /**< CMAC hardware accelerator failed. */
#define MBEDTLS_AES_BLOCK_SIZE 16 #define MBEDTLS_AES_BLOCK_SIZE 16
#define MBEDTLS_DES3_BLOCK_SIZE 8 #define MBEDTLS_DES3_BLOCK_SIZE 8
#if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_AES_C)
#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /* longest used by CMAC is AES */ #define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /* The longest block used by CMAC is that of AES. */
#else #else
#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /* longest used by CMAC is 3DES */ #define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /* The longest block used by CMAC is that of 3DES. */
#endif #endif
#if !defined(MBEDTLS_CMAC_ALT)
/** /**
* CMAC context structure - Contains internal state information only * The CMAC context structure.
*/ */
struct mbedtls_cmac_context_t struct mbedtls_cmac_context_t
{ {
/** Internal state of the CMAC algorithm */ /** The internal state of the CMAC algorithm. */
unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX]; unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX];
/** Unprocessed data - either data that was not block aligned and is still /** Unprocessed data - either data that was not block aligned and is still
* pending to be processed, or the final block */ * pending processing, or the final block. */
unsigned char unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX]; unsigned char unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX];
/** Length of data pending to be processed */ /** The length of data pending processing. */
size_t unprocessed_len; size_t unprocessed_len;
}; };
/** /**
* \brief Set the CMAC key and prepare to authenticate the input * \brief This function sets the CMAC key, and prepares to authenticate
* data. * the input data.
* Should be called with an initialized cipher context. * Must be called with an initialized cipher context.
* *
* \param ctx Cipher context. This should be a cipher context, * \param ctx The cipher context used for the CMAC operation, initialized
* initialized to be one of the following types: * as one of the following types:<ul>
* MBEDTLS_CIPHER_AES_128_ECB, MBEDTLS_CIPHER_AES_192_ECB, * <li>MBEDTLS_CIPHER_AES_128_ECB</li>
* MBEDTLS_CIPHER_AES_256_ECB or * <li>MBEDTLS_CIPHER_AES_192_ECB</li>
* MBEDTLS_CIPHER_DES_EDE3_ECB. * <li>MBEDTLS_CIPHER_AES_256_ECB</li>
* \param key CMAC key * <li>MBEDTLS_CIPHER_DES_EDE3_ECB</li></ul>
* \param keybits length of the CMAC key in bits * \param key The CMAC key.
* (must be acceptable by the cipher) * \param keybits The length of the CMAC key in bits.
* Must be supported by the cipher.
* *
* \return 0 if successful, or a cipher specific error code * \return \c 0 on success, or a cipher-specific error code.
*/ */
int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
const unsigned char *key, size_t keybits ); const unsigned char *key, size_t keybits );
/** /**
* \brief Generic CMAC process buffer. * \brief This function feeds an input buffer into an ongoing CMAC
* Called between mbedtls_cipher_cmac_starts() or * computation.
* mbedtls_cipher_cmac_reset() and
* mbedtls_cipher_cmac_finish().
* May be called repeatedly.
* *
* \param ctx CMAC context * It is called between mbedtls_cipher_cmac_starts() or
* \param input buffer holding the data * mbedtls_cipher_cmac_reset(), and mbedtls_cipher_cmac_finish().
* \param ilen length of the input data * Can be called repeatedly.
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The cipher context used for the CMAC operation.
* verification fails. * \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/ */
int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
const unsigned char *input, size_t ilen ); const unsigned char *input, size_t ilen );
/** /**
* \brief Output CMAC. * \brief This function finishes the CMAC operation, and writes
* Called after mbedtls_cipher_cmac_update(). * the result to the output buffer.
* Usually followed by mbedtls_cipher_cmac_reset(), then
* mbedtls_cipher_cmac_starts(), or mbedtls_cipher_free().
* *
* \param ctx CMAC context * It is called after mbedtls_cipher_cmac_update().
* \param output Generic CMAC checksum result * It can be followed by mbedtls_cipher_cmac_reset() and
* mbedtls_cipher_cmac_update(), or mbedtls_cipher_free().
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The cipher context used for the CMAC operation.
* verification fails. * \param output The output buffer for the CMAC checksum result.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/ */
int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output ); unsigned char *output );
/** /**
* \brief Prepare to authenticate a new message with the same key. * \brief This function prepares the authentication of another
* Called after mbedtls_cipher_cmac_finish() and before * message with the same key as the previous CMAC
* mbedtls_cipher_cmac_update(). * operation.
* *
* \param ctx CMAC context to be reset * It is called after mbedtls_cipher_cmac_finish()
* and before mbedtls_cipher_cmac_update().
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The cipher context used for the CMAC operation.
* verification fails. *
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/ */
int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ); int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
/** /**
* \brief Output = Generic_CMAC( cmac key, input buffer ) * \brief This function calculates the full generic CMAC
* on the input buffer with the provided key.
* *
* \param cipher_info message digest info * The function allocates the context, performs the
* \param key CMAC key * calculation, and frees the context.
* \param keylen length of the CMAC key in bits
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic CMAC-result
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * The CMAC result is calculated as
* verification fails. * output = generic CMAC(cmac key, input buffer).
*
*
* \param cipher_info The cipher information.
* \param key The CMAC key.
* \param keylen The length of the CMAC key in bits.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
* \param output The buffer for the generic CMAC result.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/ */
int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
const unsigned char *key, size_t keylen, const unsigned char *key, size_t keylen,
@ -140,27 +161,44 @@ int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
#if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_AES_C)
/** /**
* \brief AES-CMAC-128-PRF * \brief This function implements the AES-CMAC-PRF-128 pseudorandom
* Implementation of (AES-CMAC-PRF-128), as defined in RFC 4615 * function, as defined in
* <em>RFC-4615: The Advanced Encryption Standard-Cipher-based
* Message Authentication Code-Pseudo-Random Function-128
* (AES-CMAC-PRF-128) Algorithm for the Internet Key
* Exchange Protocol (IKE).</em>
* *
* \param key PRF key * \param key The key to use.
* \param key_len PRF key length in bytes * \param key_len The key length in Bytes.
* \param input buffer holding the input data * \param input The buffer holding the input data.
* \param in_len length of the input data in bytes * \param in_len The length of the input data in Bytes.
* \param output buffer holding the generated pseudorandom output (16 bytes) * \param output The buffer holding the generated 16 Bytes of
* pseudorandom output.
* *
* \return 0 if successful * \return \c 0 on success.
*/ */
int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len, int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
const unsigned char *input, size_t in_len, const unsigned char *input, size_t in_len,
unsigned char output[16] ); unsigned char output[16] );
#endif /* MBEDTLS_AES_C */ #endif /* MBEDTLS_AES_C */
#ifdef __cplusplus
}
#endif
#else /* !MBEDTLS_CMAC_ALT */
#include "cmac_alt.h"
#endif /* !MBEDTLS_CMAC_ALT */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) ) #if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
/** /**
* \brief Checkup routine * \brief The CMAC checkup routine.
* *
* \return 0 if successful, or 1 if the test failed * \return \c 0 on success, or \c 1 on failure.
*/ */
int mbedtls_cmac_self_test( int verbose ); int mbedtls_cmac_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ #endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */

View file

@ -5,7 +5,8 @@
* for the PolarSSL naming conventions. * for the PolarSSL naming conventions.
* *
* \deprecated Use the new names directly instead * \deprecated Use the new names directly instead
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -6,7 +6,8 @@
* This set of compile-time options may be used to enable * This set of compile-time options may be used to enable
* or disable features selectively, and reduce the global * or disable features selectively, and reduce the global
* memory footprint. * memory footprint.
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -220,7 +221,7 @@
* *
* Uncomment to get errors on using deprecated functions. * Uncomment to get errors on using deprecated functions.
*/ */
#define MBEDTLS_DEPRECATED_REMOVED /* swyter: we are explictily using the new API set */ //#define MBEDTLS_DEPRECATED_REMOVED /* ThFabba: we need md5/sha functions for bcrypt */
/* \} name SECTION: System support */ /* \} name SECTION: System support */
@ -263,20 +264,32 @@
* *
* Uncomment a macro to enable alternate implementation of the corresponding * Uncomment a macro to enable alternate implementation of the corresponding
* module. * module.
*
* \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
* use constitutes a security risk. If possible, we recommend
* avoiding dependencies on them, and considering stronger message
* digests and ciphers instead.
*
*/ */
//#define MBEDTLS_AES_ALT //#define MBEDTLS_AES_ALT
//#define MBEDTLS_ARC4_ALT //#define MBEDTLS_ARC4_ALT
//#define MBEDTLS_BLOWFISH_ALT //#define MBEDTLS_BLOWFISH_ALT
//#define MBEDTLS_CAMELLIA_ALT //#define MBEDTLS_CAMELLIA_ALT
//#define MBEDTLS_CCM_ALT
//#define MBEDTLS_CMAC_ALT
//#define MBEDTLS_DES_ALT //#define MBEDTLS_DES_ALT
//#define MBEDTLS_XTEA_ALT //#define MBEDTLS_DHM_ALT
//#define MBEDTLS_ECJPAKE_ALT
//#define MBEDTLS_GCM_ALT
//#define MBEDTLS_MD2_ALT //#define MBEDTLS_MD2_ALT
//#define MBEDTLS_MD4_ALT //#define MBEDTLS_MD4_ALT
//#define MBEDTLS_MD5_ALT //#define MBEDTLS_MD5_ALT
//#define MBEDTLS_RIPEMD160_ALT //#define MBEDTLS_RIPEMD160_ALT
//#define MBEDTLS_RSA_ALT
//#define MBEDTLS_SHA1_ALT //#define MBEDTLS_SHA1_ALT
//#define MBEDTLS_SHA256_ALT //#define MBEDTLS_SHA256_ALT
//#define MBEDTLS_SHA512_ALT //#define MBEDTLS_SHA512_ALT
//#define MBEDTLS_XTEA_ALT
/* /*
* When replacing the elliptic curve module, pleace consider, that it is * When replacing the elliptic curve module, pleace consider, that it is
* implemented with two .c files: * implemented with two .c files:
@ -316,6 +329,12 @@
* *
* Uncomment a macro to enable alternate implementation of the corresponding * Uncomment a macro to enable alternate implementation of the corresponding
* function. * function.
*
* \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
* constitutes a security risk. If possible, we recommend avoiding
* dependencies on them, and considering stronger message digests
* and ciphers instead.
*
*/ */
//#define MBEDTLS_MD2_PROCESS_ALT //#define MBEDTLS_MD2_PROCESS_ALT
//#define MBEDTLS_MD4_PROCESS_ALT //#define MBEDTLS_MD4_PROCESS_ALT
@ -331,6 +350,11 @@
//#define MBEDTLS_AES_SETKEY_DEC_ALT //#define MBEDTLS_AES_SETKEY_DEC_ALT
//#define MBEDTLS_AES_ENCRYPT_ALT //#define MBEDTLS_AES_ENCRYPT_ALT
//#define MBEDTLS_AES_DECRYPT_ALT //#define MBEDTLS_AES_DECRYPT_ALT
//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
//#define MBEDTLS_ECDSA_VERIFY_ALT
//#define MBEDTLS_ECDSA_SIGN_ALT
//#define MBEDTLS_ECDSA_GENKEY_ALT
/** /**
* \def MBEDTLS_ECP_INTERNAL_ALT * \def MBEDTLS_ECP_INTERNAL_ALT
@ -515,6 +539,9 @@
* MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
* *
* Uncomment this macro to enable weak ciphersuites * Uncomment this macro to enable weak ciphersuites
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers instead.
*/ */
//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES //#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
@ -620,6 +647,13 @@
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
* MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
* MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
*
* \warning Using DHE constitutes a security risk as it
* is not possible to validate custom DH parameters.
* If possible, it is recommended users should consider
* preferring other methods of key exchange.
* See dhm.h for more details.
*
*/ */
//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED /* swyter: we don't need PSK-based ciphers for schannel */ //#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED /* swyter: we don't need PSK-based ciphers for schannel */
@ -719,6 +753,13 @@
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
* MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
*
* \warning Using DHE constitutes a security risk as it
* is not possible to validate custom DH parameters.
* If possible, it is recommended users should consider
* preferring other methods of key exchange.
* See dhm.h for more details.
*
*/ */
#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED #define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
@ -1010,7 +1051,8 @@
/** /**
* \def MBEDTLS_RSA_NO_CRT * \def MBEDTLS_RSA_NO_CRT
* *
* Do not use the Chinese Remainder Theorem for the RSA private operation. * Do not use the Chinese Remainder Theorem
* for the RSA private operation.
* *
* Uncomment this macro to disable the use of CRT in RSA. * Uncomment this macro to disable the use of CRT in RSA.
* *
@ -1157,6 +1199,13 @@
* misuse/misunderstand. * misuse/misunderstand.
* *
* Comment this to disable support for renegotiation. * Comment this to disable support for renegotiation.
*
* \note Even if this option is disabled, both client and server are aware
* of the Renegotiation Indication Extension (RFC 5746) used to
* prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
* (See \c mbedtls_ssl_conf_legacy_renegotiation for the
* configuration of this extension).
*
*/ */
#define MBEDTLS_SSL_RENEGOTIATION #define MBEDTLS_SSL_RENEGOTIATION
@ -1365,6 +1414,30 @@
*/ */
#define MBEDTLS_SSL_TRUNCATED_HMAC #define MBEDTLS_SSL_TRUNCATED_HMAC
/**
* \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
*
* Fallback to old (pre-2.7), non-conforming implementation of the truncated
* HMAC extension which also truncates the HMAC key. Note that this option is
* only meant for a transitory upgrade period and is likely to be removed in
* a future version of the library.
*
* \warning The old implementation is non-compliant and has a security weakness
* (2^80 brute force attack on the HMAC key used for a single,
* uninterrupted connection). This should only be enabled temporarily
* when (1) the use of truncated HMAC is essential in order to save
* bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
* the fixed implementation yet (pre-2.7).
*
* \deprecated This option is deprecated and will likely be removed in a
* future version of Mbed TLS.
*
* Uncomment to fallback to old, non-compliant truncated HMAC implementation.
*
* Requires: MBEDTLS_SSL_TRUNCATED_HMAC
*/
//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
/** /**
* \def MBEDTLS_THREADING_ALT * \def MBEDTLS_THREADING_ALT
* *
@ -1598,6 +1671,11 @@
* MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
* MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
* MBEDTLS_TLS_PSK_WITH_RC4_128_SHA * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. If possible, we recommend avoidng dependencies on
* it, and considering stronger ciphers instead.
*
*/ */
#define MBEDTLS_ARC4_C #define MBEDTLS_ARC4_C
@ -1651,6 +1729,7 @@
* library/ecp.c * library/ecp.c
* library/ecdsa.c * library/ecdsa.c
* library/rsa.c * library/rsa.c
* library/rsa_internal.c
* library/ssl_tls.c * library/ssl_tls.c
* *
* This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
@ -1825,6 +1904,9 @@
* MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
* *
* PEM_PARSE uses DES/3DES for decrypting encrypted keys. * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers instead.
*/ */
#define MBEDTLS_DES_C #define MBEDTLS_DES_C
@ -1839,6 +1921,13 @@
* *
* This module is used by the following key exchanges: * This module is used by the following key exchanges:
* DHE-RSA, DHE-PSK * DHE-RSA, DHE-PSK
*
* \warning Using DHE constitutes a security risk as it
* is not possible to validate custom DH parameters.
* If possible, it is recommended users should consider
* preferring other methods of key exchange.
* See dhm.h for more details.
*
*/ */
#define MBEDTLS_DHM_C #define MBEDTLS_DHM_C
@ -2004,6 +2093,11 @@
* Caller: * Caller:
* *
* Uncomment to enable support for (rare) MD2-signed X.509 certs. * Uncomment to enable support for (rare) MD2-signed X.509 certs.
*
* \warning MD2 is considered a weak message digest and its use constitutes a
* security risk. If possible, we recommend avoiding dependencies on
* it, and considering stronger message digests instead.
*
*/ */
//#define MBEDTLS_MD2_C //#define MBEDTLS_MD2_C
@ -2016,6 +2110,11 @@
* Caller: * Caller:
* *
* Uncomment to enable support for (rare) MD4-signed X.509 certs. * Uncomment to enable support for (rare) MD4-signed X.509 certs.
*
* \warning MD4 is considered a weak message digest and its use constitutes a
* security risk. If possible, we recommend avoiding dependencies on
* it, and considering stronger message digests instead.
*
*/ */
//#define MBEDTLS_MD4_C //#define MBEDTLS_MD4_C
@ -2029,8 +2128,15 @@
* library/pem.c * library/pem.c
* library/ssl_tls.c * library/ssl_tls.c
* *
* This module is required for SSL/TLS and X.509. * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
* PEM_PARSE uses MD5 for decrypting encrypted keys. * depending on the handshake parameters. Further, it is used for checking
* MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
* encrypted keys.
*
* \warning MD5 is considered a weak message digest and its use constitutes a
* security risk. If possible, we recommend avoiding dependencies on
* it, and considering stronger message digests instead.
*
*/ */
#define MBEDTLS_MD5_C #define MBEDTLS_MD5_C
@ -2266,6 +2372,7 @@
* Enable the RSA public-key cryptosystem. * Enable the RSA public-key cryptosystem.
* *
* Module: library/rsa.c * Module: library/rsa.c
* library/rsa_internal.c
* Caller: library/ssl_cli.c * Caller: library/ssl_cli.c
* library/ssl_srv.c * library/ssl_srv.c
* library/ssl_tls.c * library/ssl_tls.c
@ -2292,6 +2399,11 @@
* *
* This module is required for SSL/TLS up to version 1.1, for TLS 1.2 * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
* depending on the handshake parameters, and for SHA1-signed certificates. * depending on the handshake parameters, and for SHA1-signed certificates.
*
* \warning SHA-1 is considered a weak message digest and its use constitutes
* a security risk. If possible, we recommend avoiding dependencies
* on it, and considering stronger message digests instead.
*
*/ */
#define MBEDTLS_SHA1_C #define MBEDTLS_SHA1_C
@ -2680,8 +2792,13 @@
* Allow SHA-1 in the default TLS configuration for certificate signing. * Allow SHA-1 in the default TLS configuration for certificate signing.
* Without this build-time option, SHA-1 support must be activated explicitly * Without this build-time option, SHA-1 support must be activated explicitly
* through mbedtls_ssl_conf_cert_profile. Turning on this option is not * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
* recommended because of it is possible to generte SHA-1 collisions, however * recommended because of it is possible to generate SHA-1 collisions, however
* this may be safe for legacy infrastructure where additional controls apply. * this may be safe for legacy infrastructure where additional controls apply.
*
* \warning SHA-1 is considered a weak message digest and its use constitutes
* a security risk. If possible, we recommend avoiding dependencies
* on it, and considering stronger message digests instead.
*
*/ */
// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES // #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
@ -2692,14 +2809,20 @@
* The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by
* default. At the time of writing, there is no practical attack on the use * default. At the time of writing, there is no practical attack on the use
* of SHA-1 in handshake signatures, hence this option is turned on by default * of SHA-1 in handshake signatures, hence this option is turned on by default
* for compatibility with existing peers. * to preserve compatibility with existing peers, but the general
* warning applies nonetheless:
*
* \warning SHA-1 is considered a weak message digest and its use constitutes
* a security risk. If possible, we recommend avoiding dependencies
* on it, and considering stronger message digests instead.
*
*/ */
#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
/* \} name SECTION: Customisation configuration options */ /* \} name SECTION: Customisation configuration options */
/* Target and application specific configurations */ /* Target and application specific configurations */
//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h" //#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "target_config.h"
#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE) #if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE)
#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE #include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE

View file

@ -1,9 +1,13 @@
/** /**
* \file ctr_drbg.h * \file ctr_drbg.h
* *
* \brief CTR_DRBG based on AES-256 (NIST SP 800-90) * \brief CTR_DRBG is based on AES-256, as defined in <em>NIST SP 800-90A:
* Recommendation for Random Number Generation Using Deterministic
* Random Bit Generators</em>.
* *
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved */
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,90 +24,108 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_CTR_DRBG_H #ifndef MBEDTLS_CTR_DRBG_H
#define MBEDTLS_CTR_DRBG_H #define MBEDTLS_CTR_DRBG_H
#include "aes.h" #include "aes.h"
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h" #include "threading.h"
#endif #endif
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */ #define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */ #define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< The requested random buffer length is too big. */
#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */ #define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< The input (entropy + additional data) is too large. */
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read/write error in file. */ #define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< Block size used by the cipher */ #define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< Key size used by the cipher */ #define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher. */
#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) #define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) #define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
/**< The seed length (counter + AES key) */
/** /**
* \name SECTION: Module settings * \name SECTION: Module settings
* *
* The configuration options you can set for this module are in this section. * The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line. * Either change them in config.h or define them using the compiler command
* line.
* \{ * \{
*/ */
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48
/**< The amount of entropy used per seed by default:
* <ul><li>48 with SHA-512.</li>
* <li>32 with SHA-256.</li></ul>
*/
#else #else
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
/**< Amount of entropy used per seed by default:
* <ul><li>48 with SHA-512.</li>
* <li>32 with SHA-256.</li></ul>
*/
#endif #endif
#endif #endif
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000
/**< The interval before reseed is performed by default. */
#endif #endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT) #if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ #define MBEDTLS_CTR_DRBG_MAX_INPUT 256
/**< The maximum number of additional input Bytes. */
#endif #endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST) #if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST)
#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ #define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024
/**< The maximum number of requested Bytes per call. */
#endif #endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ #define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384
/**< The maximum size of seed or reseed buffer. */
#endif #endif
/* \} name SECTION: Module settings */ /* \} name SECTION: Module settings */
#define MBEDTLS_CTR_DRBG_PR_OFF 0 /**< No prediction resistance */ #define MBEDTLS_CTR_DRBG_PR_OFF 0
#define MBEDTLS_CTR_DRBG_PR_ON 1 /**< Prediction resistance enabled */ /**< Prediction resistance is disabled. */
#define MBEDTLS_CTR_DRBG_PR_ON 1
/**< Prediction resistance is enabled. */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** /**
* \brief CTR_DRBG context structure * \brief The CTR_DRBG context structure.
*/ */
typedef struct typedef struct
{ {
unsigned char counter[16]; /*!< counter (V) */ unsigned char counter[16]; /*!< The counter (V). */
int reseed_counter; /*!< reseed counter */ int reseed_counter; /*!< The reseed counter. */
int prediction_resistance; /*!< enable prediction resistance (Automatic int prediction_resistance; /*!< This determines whether prediction
reseed before every random generation) */ resistance is enabled, that is
size_t entropy_len; /*!< amount of entropy grabbed on each whether to systematically reseed before
(re)seed */ each random generation. */
int reseed_interval; /*!< reseed interval */ size_t entropy_len; /*!< The amount of entropy grabbed on each
seed or reseed operation. */
int reseed_interval; /*!< The reseed interval. */
mbedtls_aes_context aes_ctx; /*!< AES context */ mbedtls_aes_context aes_ctx; /*!< The AES context. */
/* /*
* Callbacks (Entropy) * Callbacks (Entropy)
*/ */
int (*f_entropy)(void *, unsigned char *, size_t); int (*f_entropy)(void *, unsigned char *, size_t);
/*!< The entropy callback function. */
void *p_entropy; /*!< context for the entropy function */ void *p_entropy; /*!< The context for the entropy function. */
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex; mbedtls_threading_mutex_t mutex;
@ -112,31 +134,32 @@ typedef struct
mbedtls_ctr_drbg_context; mbedtls_ctr_drbg_context;
/** /**
* \brief CTR_DRBG context initialization * \brief This function initializes the CTR_DRBG context,
* Makes the context ready for mbedtls_ctr_drbg_seed() or * and prepares it for mbedtls_ctr_drbg_seed()
* mbedtls_ctr_drbg_free(). * or mbedtls_ctr_drbg_free().
* *
* \param ctx CTR_DRBG context to be initialized * \param ctx The CTR_DRBG context to initialize.
*/ */
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
/** /**
* \brief CTR_DRBG initial seeding * \brief This function seeds and sets up the CTR_DRBG
* Seed and setup entropy source for future reseeds. * entropy source for future reseeds.
* *
* Note: Personalization data can be provided in addition to the more generic * \note Personalization data can be provided in addition to the more generic
* entropy source to make this instantiation as unique as possible. * entropy source, to make this instantiation as unique as possible.
* *
* \param ctx CTR_DRBG context to be seeded * \param ctx The CTR_DRBG context to seed.
* \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer * \param f_entropy The entropy callback, taking as arguments the
* length) * \p p_entropy context, the buffer to fill, and the
* \param p_entropy Entropy context length of the buffer.
* \param custom Personalization data (Device specific identifiers) * \param p_entropy The entropy context.
* (Can be NULL) * \param custom Personalization data, that is device-specific
* \param len Length of personalization data identifiers. Can be NULL.
* \param len The length of the personalization data.
* *
* \return 0 if successful, or * \return \c 0 on success, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
*/ */
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t), int (*f_entropy)(void *, unsigned char *, size_t),
@ -145,138 +168,147 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
size_t len ); size_t len );
/** /**
* \brief Clear CTR_CRBG context data * \brief This function clears CTR_CRBG context data.
* *
* \param ctx CTR_DRBG context to clear * \param ctx The CTR_DRBG context to clear.
*/ */
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ); void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
/** /**
* \brief Enable / disable prediction resistance (Default: Off) * \brief This function turns prediction resistance on or off.
* The default value is off.
* *
* Note: If enabled, entropy is used for ctx->entropy_len before each call! * \note If enabled, entropy is gathered at the beginning of
* Only use this if you have ample supply of good entropy! * every call to mbedtls_ctr_drbg_random_with_add().
* Only use this if your entropy source has sufficient
* throughput.
* *
* \param ctx CTR_DRBG context * \param ctx The CTR_DRBG context.
* \param resistance MBEDTLS_CTR_DRBG_PR_ON or MBEDTLS_CTR_DRBG_PR_OFF * \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF.
*/ */
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
int resistance ); int resistance );
/** /**
* \brief Set the amount of entropy grabbed on each (re)seed * \brief This function sets the amount of entropy grabbed on each
* (Default: MBEDTLS_CTR_DRBG_ENTROPY_LEN) * seed or reseed. The default value is
* #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
* *
* \param ctx CTR_DRBG context * \param ctx The CTR_DRBG context.
* \param len Amount of entropy to grab * \param len The amount of entropy to grab.
*/ */
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
size_t len ); size_t len );
/** /**
* \brief Set the reseed interval * \brief This function sets the reseed interval.
* (Default: MBEDTLS_CTR_DRBG_RESEED_INTERVAL) * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
* *
* \param ctx CTR_DRBG context * \param ctx The CTR_DRBG context.
* \param interval Reseed interval * \param interval The reseed interval.
*/ */
void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
int interval ); int interval );
/** /**
* \brief CTR_DRBG reseeding (extracts data from entropy source) * \brief This function reseeds the CTR_DRBG context, that is
* extracts data from the entropy source.
* *
* \param ctx CTR_DRBG context * \param ctx The CTR_DRBG context.
* \param additional Additional data to add to state (Can be NULL) * \param additional Additional data to add to the state. Can be NULL.
* \param len Length of additional data * \param len The length of the additional data.
* *
* \return 0 if successful, or * \return \c 0 on success, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
*/ */
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t len ); const unsigned char *additional, size_t len );
/** /**
* \brief CTR_DRBG update state * \brief This function updates the state of the CTR_DRBG context.
* *
* \param ctx CTR_DRBG context * \param ctx The CTR_DRBG context.
* \param additional Additional data to update state with * \param additional The data to update the state with.
* \param add_len Length of additional data * \param add_len Length of \p additional data.
* *
* \note If add_len is greater than MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, * \note If \p add_len is greater than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT,
* only the first MBEDTLS_CTR_DRBG_MAX_SEED_INPUT bytes are used, * only the first #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
* the remaining ones are silently discarded. * The remaining Bytes are silently discarded.
*/ */
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t add_len ); const unsigned char *additional, size_t add_len );
/** /**
* \brief CTR_DRBG generate random with additional update input * \brief This function updates a CTR_DRBG instance with additional
* data and uses it to generate random data.
* *
* Note: Automatically reseeds if reseed_counter is reached. * \note The function automatically reseeds if the reseed counter is exceeded.
* *
* \param p_rng CTR_DRBG context * \param p_rng The CTR_DRBG context. This must be a pointer to a
* \param output Buffer to fill * #mbedtls_ctr_drbg_context structure.
* \param output_len Length of the buffer * \param output The buffer to fill.
* \param additional Additional data to update with (Can be NULL) * \param output_len The length of the buffer.
* \param add_len Length of additional data * \param additional Additional data to update. Can be NULL.
* \param add_len The length of the additional data.
* *
* \return 0 if successful, or * \return \c 0 on success, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
*/ */
int mbedtls_ctr_drbg_random_with_add( void *p_rng, int mbedtls_ctr_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len, unsigned char *output, size_t output_len,
const unsigned char *additional, size_t add_len ); const unsigned char *additional, size_t add_len );
/** /**
* \brief CTR_DRBG generate random * \brief This function uses CTR_DRBG to generate random data.
* *
* Note: Automatically reseeds if reseed_counter is reached. * \note The function automatically reseeds if the reseed counter is exceeded.
* *
* \param p_rng CTR_DRBG context * \param p_rng The CTR_DRBG context. This must be a pointer to a
* \param output Buffer to fill * #mbedtls_ctr_drbg_context structure.
* \param output_len Length of the buffer * \param output The buffer to fill.
* \param output_len The length of the buffer.
* *
* \return 0 if successful, or * \return \c 0 on success, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
*/ */
int mbedtls_ctr_drbg_random( void *p_rng, int mbedtls_ctr_drbg_random( void *p_rng,
unsigned char *output, size_t output_len ); unsigned char *output, size_t output_len );
#if defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_FS_IO)
/** /**
* \brief Write a seed file * \brief This function writes a seed file.
* *
* \param ctx CTR_DRBG context * \param ctx The CTR_DRBG context.
* \param path Name of the file * \param path The name of the file.
* *
* \return 0 if successful, * \return \c 0 on success,
* MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or * #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
* failure.
*/ */
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
/** /**
* \brief Read and update a seed file. Seed is added to this * \brief This function reads and updates a seed file. The seed
* instance * is added to this instance.
* *
* \param ctx CTR_DRBG context * \param ctx The CTR_DRBG context.
* \param path Name of the file * \param path The name of the file.
* *
* \return 0 if successful, * \return \c 0 on success,
* MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, * #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error,
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG * #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
*/ */
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */
/** /**
* \brief Checkup routine * \brief The CTR_DRBG checkup routine.
* *
* \return 0 if successful, or 1 if the test failed * \return \c 0 on success, or \c 1 on failure.
*/ */
int mbedtls_ctr_drbg_self_test( int verbose ); int mbedtls_ctr_drbg_self_test( int verbose );

View file

@ -2,7 +2,8 @@
* \file debug.h * \file debug.h
* *
* \brief Functions for controlling and providing debug output from the library. * \brief Functions for controlling and providing debug output from the library.
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -3,6 +3,11 @@
* *
* \brief DES block cipher * \brief DES block cipher
* *
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -21,6 +26,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*
*/ */
#ifndef MBEDTLS_DES_H #ifndef MBEDTLS_DES_H
#define MBEDTLS_DES_H #define MBEDTLS_DES_H
@ -38,6 +44,7 @@
#define MBEDTLS_DES_DECRYPT 0 #define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ #define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */
#define MBEDTLS_DES_KEY_SIZE 8 #define MBEDTLS_DES_KEY_SIZE 8
@ -51,6 +58,10 @@ extern "C" {
/** /**
* \brief DES context structure * \brief DES context structure
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
typedef struct typedef struct
{ {
@ -71,6 +82,10 @@ mbedtls_des3_context;
* \brief Initialize DES context * \brief Initialize DES context
* *
* \param ctx DES context to be initialized * \param ctx DES context to be initialized
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
void mbedtls_des_init( mbedtls_des_context *ctx ); void mbedtls_des_init( mbedtls_des_context *ctx );
@ -78,6 +93,10 @@ void mbedtls_des_init( mbedtls_des_context *ctx );
* \brief Clear DES context * \brief Clear DES context
* *
* \param ctx DES context to be cleared * \param ctx DES context to be cleared
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
void mbedtls_des_free( mbedtls_des_context *ctx ); void mbedtls_des_free( mbedtls_des_context *ctx );
@ -102,6 +121,10 @@ void mbedtls_des3_free( mbedtls_des3_context *ctx );
* a parity bit to allow verification. * a parity bit to allow verification.
* *
* \param key 8-byte secret key * \param key 8-byte secret key
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] ); void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
@ -114,6 +137,10 @@ void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
* \param key 8-byte secret key * \param key 8-byte secret key
* *
* \return 0 is parity was ok, 1 if parity was not correct. * \return 0 is parity was ok, 1 if parity was not correct.
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
@ -123,6 +150,10 @@ int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SI
* \param key 8-byte secret key * \param key 8-byte secret key
* *
* \return 0 if no weak key was found, 1 if a weak key was identified. * \return 0 if no weak key was found, 1 if a weak key was identified.
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
@ -133,6 +164,10 @@ int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
* \param key 8-byte secret key * \param key 8-byte secret key
* *
* \return 0 * \return 0
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
@ -143,6 +178,10 @@ int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MB
* \param key 8-byte secret key * \param key 8-byte secret key
* *
* \return 0 * \return 0
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
@ -198,6 +237,10 @@ int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
* \param output 64-bit output block * \param output 64-bit output block
* *
* \return 0 if successful * \return 0 if successful
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx, int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
const unsigned char input[8], const unsigned char input[8],
@ -221,6 +264,10 @@ int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
* \param iv initialization vector (updated after use) * \param iv initialization vector (updated after use)
* \param input buffer holding the input data * \param input buffer holding the input data
* \param output buffer holding the output data * \param output buffer holding the output data
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
int mode, int mode,
@ -279,6 +326,10 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
* *
* \param SK Round keys * \param SK Round keys
* \param key Base key * \param key Base key
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/ */
void mbedtls_des_setkey( uint32_t SK[32], void mbedtls_des_setkey( uint32_t SK[32],
const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); const unsigned char key[MBEDTLS_DES_KEY_SIZE] );

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,18 @@
/** /**
* \file ecdh.h * \file ecdh.h
* *
* \brief Elliptic curve Diffie-Hellman * \brief The Elliptic Curve Diffie-Hellman (ECDH) protocol APIs.
* *
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * ECDH is an anonymous key agreement protocol allowing two parties to
* establish a shared secret over an insecure channel. Each party must have an
* elliptic-curve publicprivate key pair.
*
* For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
* Pair-Wise Key Establishment Schemes Using Discrete Logarithm
* Cryptography</em>.
*/
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,8 +29,9 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_ECDH_H #ifndef MBEDTLS_ECDH_H
#define MBEDTLS_ECDH_H #define MBEDTLS_ECDH_H
@ -32,7 +42,9 @@ extern "C" {
#endif #endif
/** /**
* When importing from an EC key, select if it is our key or the peer's key * Defines the source of the imported EC key:
* <ul><li>Our key.</li>
* <li>The key of the peer.</li></ul>
*/ */
typedef enum typedef enum
{ {
@ -41,56 +53,67 @@ typedef enum
} mbedtls_ecdh_side; } mbedtls_ecdh_side;
/** /**
* \brief ECDH context structure * \brief The ECDH context structure.
*/ */
typedef struct typedef struct
{ {
mbedtls_ecp_group grp; /*!< elliptic curve used */ mbedtls_ecp_group grp; /*!< The elliptic curve used. */
mbedtls_mpi d; /*!< our secret value (private key) */ mbedtls_mpi d; /*!< The private key. */
mbedtls_ecp_point Q; /*!< our public value (public key) */ mbedtls_ecp_point Q; /*!< The public key. */
mbedtls_ecp_point Qp; /*!< peer's public value (public key) */ mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */
mbedtls_mpi z; /*!< shared secret */ mbedtls_mpi z; /*!< The shared secret. */
int point_format; /*!< format for point export in TLS messages */ int point_format; /*!< The format of point export in TLS messages. */
mbedtls_ecp_point Vi; /*!< blinding value (for later) */ mbedtls_ecp_point Vi; /*!< The blinding value. */
mbedtls_ecp_point Vf; /*!< un-blinding value (for later) */ mbedtls_ecp_point Vf; /*!< The unblinding value. */
mbedtls_mpi _d; /*!< previous d (for later) */ mbedtls_mpi _d; /*!< The previous \p d. */
} }
mbedtls_ecdh_context; mbedtls_ecdh_context;
/** /**
* \brief Generate a public key. * \brief This function generates an ECDH keypair on an elliptic
* Raw function that only does the core computation. * curve.
* *
* \param grp ECP group * This function performs the first of two core computations
* \param d Destination MPI (secret exponent, aka private key) * implemented during the ECDH key exchange. The second core
* \param Q Destination point (public key) * computation is performed by mbedtls_ecdh_compute_shared().
* \param f_rng RNG function
* \param p_rng RNG parameter
* *
* \return 0 if successful, * \param grp The ECP group.
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code * \param d The destination MPI (private key).
* \param Q The destination point (public key).
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng ); void *p_rng );
/** /**
* \brief Compute shared secret * \brief This function computes the shared secret.
* Raw function that only does the core computation.
* *
* \param grp ECP group * This function performs the second of two core computations
* \param z Destination MPI (shared secret) * implemented during the ECDH key exchange. The first core
* \param Q Public key from other party * computation is performed by mbedtls_ecdh_gen_public().
* \param d Our secret exponent (private key)
* \param f_rng RNG function (see notes)
* \param p_rng RNG parameter
* *
* \return 0 if successful, * \param grp The ECP group.
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code * \param z The destination MPI (shared secret).
* \param Q The public key from another party.
* \param d Our secret exponent (private key).
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
* *
* \note If f_rng is not NULL, it is used to implement * \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
*
* \see ecp.h
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against potential elaborate timing * countermeasures against potential elaborate timing
* attacks, see \c mbedtls_ecp_mul() for details. * attacks. For more information, see mbedtls_ecp_mul().
*/ */
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d, const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
@ -98,34 +121,41 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
void *p_rng ); void *p_rng );
/** /**
* \brief Initialize context * \brief This function initializes an ECDH context.
* *
* \param ctx Context to initialize * \param ctx The ECDH context to initialize.
*/ */
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ); void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
/** /**
* \brief Free context * \brief This function frees a context.
* *
* \param ctx Context to free * \param ctx The context to free.
*/ */
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ); void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
/** /**
* \brief Generate a public key and a TLS ServerKeyExchange payload. * \brief This function generates a public key and a TLS
* (First function used by a TLS server for ECDHE.) * ServerKeyExchange payload.
* *
* \param ctx ECDH context * This is the first function used by a TLS server for ECDHE
* \param olen number of chars written * ciphersuites.
* \param buf destination buffer
* \param blen length of buffer
* \param f_rng RNG function
* \param p_rng RNG parameter
* *
* \note This function assumes that ctx->grp has already been * \param ctx The ECDH context.
* properly set (for example using mbedtls_ecp_group_load). * \param olen The number of characters written.
* \param buf The destination buffer.
* \param blen The length of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
* *
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code * \note This function assumes that the ECP group (grp) of the
* \p ctx context has already been properly set,
* for example, using mbedtls_ecp_group_load().
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen, unsigned char *buf, size_t blen,
@ -133,45 +163,63 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
void *p_rng ); void *p_rng );
/** /**
* \brief Parse and procress a TLS ServerKeyExhange payload. * \brief This function parses and processes a TLS ServerKeyExhange
* (First function used by a TLS client for ECDHE.) * payload.
* *
* \param ctx ECDH context * This is the first function used by a TLS client for ECDHE
* \param buf pointer to start of input buffer * ciphersuites.
* \param end one past end of buffer
* *
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code * \param ctx The ECDH context.
* \param buf The pointer to the start of the input buffer.
* \param end The address for one Byte past the end of the buffer.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf, const unsigned char *end ); const unsigned char **buf, const unsigned char *end );
/** /**
* \brief Setup an ECDH context from an EC key. * \brief This function sets up an ECDH context from an EC key.
* (Used by clients and servers in place of the
* ServerKeyEchange for static ECDH: import ECDH parameters
* from a certificate's EC key information.)
* *
* \param ctx ECDH constext to set * It is used by clients and servers in place of the
* \param key EC key to use * ServerKeyEchange for static ECDH, and imports ECDH
* \param side Is it our key (1) or the peer's key (0) ? * parameters from the EC key information of a certificate.
* *
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code * \param ctx The ECDH context to set up.
* \param key The EC key to use.
* \param side Defines the source of the key:
* <ul><li>1: Our key.</li>
<li>0: The key of the peer.</li></ul>
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side ); mbedtls_ecdh_side side );
/** /**
* \brief Generate a public key and a TLS ClientKeyExchange payload. * \brief This function generates a public key and a TLS
* (Second function used by a TLS client for ECDH(E).) * ClientKeyExchange payload.
* *
* \param ctx ECDH context * This is the second function used by a TLS client for ECDH(E)
* \param olen number of bytes actually written * ciphersuites.
* \param buf destination buffer
* \param blen size of destination buffer
* \param f_rng RNG function
* \param p_rng RNG parameter
* *
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code * \param ctx The ECDH context.
* \param olen The number of Bytes written.
* \param buf The destination buffer.
* \param blen The size of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen, unsigned char *buf, size_t blen,
@ -179,30 +227,45 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
void *p_rng ); void *p_rng );
/** /**
* \brief Parse and process a TLS ClientKeyExchange payload. * \brief This function parses and processes a TLS ClientKeyExchange
* (Second function used by a TLS server for ECDH(E).) * payload.
* *
* \param ctx ECDH context * This is the second function used by a TLS server for ECDH(E)
* \param buf start of input buffer * ciphersuites.
* \param blen length of input buffer
* *
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code * \param ctx The ECDH context.
* \param buf The start of the input buffer.
* \param blen The length of the input buffer.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
const unsigned char *buf, size_t blen ); const unsigned char *buf, size_t blen );
/** /**
* \brief Derive and export the shared secret. * \brief This function derives and exports the shared secret.
* (Last function used by both TLS client en servers.)
* *
* \param ctx ECDH context * This is the last function used by both TLS client
* \param olen number of bytes written * and servers.
* \param buf destination buffer
* \param blen buffer length
* \param f_rng RNG function, see notes for \c mbedtls_ecdh_compute_shared()
* \param p_rng RNG parameter
* *
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code * \param ctx The ECDH context.
* \param olen The number of Bytes written.
* \param buf The destination buffer.
* \param blen The length of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
* on failure.
*
* \see ecp.h
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against potential elaborate timing
* attacks. For more information, see mbedtls_ecp_mul().
*/ */
int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen, unsigned char *buf, size_t blen,

View file

@ -1,9 +1,16 @@
/** /**
* \file ecdsa.h * \file ecdsa.h
* *
* \brief Elliptic curve DSA * \brief The Elliptic Curve Digital Signature Algorithm (ECDSA).
* *
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * ECDSA is defined in <em>Standards for Efficient Cryptography Group (SECG):
* SEC1 Elliptic Curve Cryptography</em>.
* The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve
* Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
*
*/
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,8 +27,9 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_ECDSA_H #ifndef MBEDTLS_ECDSA_H
#define MBEDTLS_ECDSA_H #define MBEDTLS_ECDSA_H
@ -29,7 +37,7 @@
#include "md.h" #include "md.h"
/* /*
* RFC 4492 page 20: * RFC-4492 page 20:
* *
* Ecdsa-Sig-Value ::= SEQUENCE { * Ecdsa-Sig-Value ::= SEQUENCE {
* r INTEGER, * r INTEGER,
@ -45,11 +53,11 @@
#if MBEDTLS_ECP_MAX_BYTES > 124 #if MBEDTLS_ECP_MAX_BYTES > 124
#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN" #error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN"
#endif #endif
/** Maximum size of an ECDSA signature in bytes */ /** The maximal size of an ECDSA signature in Bytes. */
#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) ) #define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
/** /**
* \brief ECDSA context structure * \brief The ECDSA context structure.
*/ */
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
@ -58,25 +66,30 @@ extern "C" {
#endif #endif
/** /**
* \brief Compute ECDSA signature of a previously hashed message * \brief This function computes the ECDSA signature of a
* previously-hashed message.
* *
* \note The deterministic version is usually prefered. * \note The deterministic version is usually preferred.
* *
* \param grp ECP group * \param grp The ECP group.
* \param r First output integer * \param r The first output integer.
* \param s Second output integer * \param s The second output integer.
* \param d Private signing key * \param d The private signing key.
* \param buf Message hash * \param buf The message hash.
* \param blen Length of buf * \param blen The length of \p buf.
* \param f_rng RNG function * \param f_rng The RNG function.
* \param p_rng RNG parameter * \param p_rng The RNG parameter.
* *
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as * bitlength of the group order, then the hash is truncated
* prescribed by SEC1 4.1.3 step 5. * as defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
* *
* \return 0 if successful, * \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code * or \c MBEDTLS_MPI_XXX error code on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
@ -84,23 +97,31 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/** /**
* \brief Compute ECDSA signature of a previously hashed message, * \brief This function computes the ECDSA signature of a
* deterministic version (RFC 6979). * previously-hashed message, deterministic version.
* For more information, see <em>RFC-6979: Deterministic
* Usage of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
* *
* \param grp ECP group * \param grp The ECP group.
* \param r First output integer * \param r The first output integer.
* \param s Second output integer * \param s The second output integer.
* \param d Private signing key * \param d The private signing key.
* \param buf Message hash * \param buf The message hash.
* \param blen Length of buf * \param blen The length of \p buf.
* \param md_alg MD algorithm used to hash the message * \param md_alg The MD algorithm used to hash the message.
* *
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as * bitlength of the group order, then the hash is truncated as
* prescribed by SEC1 4.1.3 step 5. * defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
* *
* \return 0 if successful, * \return \c 0 on success,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code * or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
@ -108,55 +129,73 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/** /**
* \brief Verify ECDSA signature of a previously hashed message * \brief This function verifies the ECDSA signature of a
* previously-hashed message.
* *
* \param grp ECP group * \param grp The ECP group.
* \param buf Message hash * \param buf The message hash.
* \param blen Length of buf * \param blen The length of \p buf.
* \param Q Public key to use for verification * \param Q The public key to use for verification.
* \param r First integer of the signature * \param r The first integer of the signature.
* \param s Second integer of the signature * \param s The second integer of the signature.
* *
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as * bitlength of the group order, then the hash is truncated as
* prescribed by SEC1 4.1.4 step 3. * defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.4, step 3.
* *
* \return 0 if successful, * \return \c 0 on success,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid * #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code * or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure for any other reason.
*
* \see ecp.h
*/ */
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen, const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s); const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s);
/** /**
* \brief Compute ECDSA signature and write it to buffer, * \brief This function computes the ECDSA signature and writes it
* serialized as defined in RFC 4492 page 20. * to a buffer, serialized as defined in <em>RFC-4492:
* (Not thread-safe to use same context in multiple threads) * Elliptic Curve Cryptography (ECC) Cipher Suites for
* Transport Layer Security (TLS)</em>.
* *
* \note The deterministic version (RFC 6979) is used if * \warning It is not thread-safe to use the same context in
* MBEDTLS_ECDSA_DETERMINISTIC is defined. * multiple threads.
* *
* \param ctx ECDSA context * \note The deterministic version is used if
* \param md_alg Algorithm that was used to hash the message * #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more
* \param hash Message hash * information, see <em>RFC-6979: Deterministic Usage
* \param hlen Length of hash * of the Digital Signature Algorithm (DSA) and Elliptic
* \param sig Buffer that will hold the signature * Curve Digital Signature Algorithm (ECDSA)</em>.
* \param slen Length of the signature written
* \param f_rng RNG function
* \param p_rng RNG parameter
* *
* \note The "sig" buffer must be at least as large as twice the * \param ctx The ECDSA context.
* size of the curve used, plus 9 (eg. 73 bytes if a 256-bit * \param md_alg The message digest that was used to hash the message.
* curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe. * \param hash The message hash.
* \param hlen The length of the hash.
* \param sig The buffer that holds the signature.
* \param slen The length of the signature written.
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \note The \p sig buffer must be at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* *
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as * bitlength of the group order, then the hash is truncated as
* prescribed by SEC1 4.1.3 step 5. * defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
* *
* \return 0 if successful, * \return \c 0 on success,
* or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or * or an \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* MBEDTLS_ERR_ASN1_XXX error code * \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen, const unsigned char *hash, size_t hlen,
@ -172,31 +211,43 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
#define MBEDTLS_DEPRECATED #define MBEDTLS_DEPRECATED
#endif #endif
/** /**
* \brief Compute ECDSA signature and write it to buffer, * \brief This function computes an ECDSA signature and writes it to a buffer,
* serialized as defined in RFC 4492 page 20. * serialized as defined in <em>RFC-4492: Elliptic Curve Cryptography
* Deterministic version, RFC 6979. * (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
* (Not thread-safe to use same context in multiple threads) *
* The deterministic version is defined in <em>RFC-6979:
* Deterministic Usage of the Digital Signature Algorithm (DSA) and
* Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \warning It is not thread-safe to use the same context in
* multiple threads.
* *
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in 2.0.0 * \deprecated Superseded by mbedtls_ecdsa_write_signature() in 2.0.0
* *
* \param ctx ECDSA context * \param ctx The ECDSA context.
* \param hash Message hash * \param hash The Message hash.
* \param hlen Length of hash * \param hlen The length of the hash.
* \param sig Buffer that will hold the signature * \param sig The buffer that holds the signature.
* \param slen Length of the signature written * \param slen The length of the signature written.
* \param md_alg MD algorithm used to hash the message * \param md_alg The MD algorithm used to hash the message.
* *
* \note The "sig" buffer must be at least as large as twice the * \note The \p sig buffer must be at least twice as large as the
* size of the curve used, plus 9 (eg. 73 bytes if a 256-bit * size of the curve used, plus 9. For example, 73 Bytes if a
* curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe. * 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* *
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as * bitlength of the group order, then the hash is truncated as
* prescribed by SEC1 4.1.3 step 5. * defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
* *
* \return 0 if successful, * \return \c 0 on success,
* or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or * or an \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* MBEDTLS_ERR_ASN1_XXX error code * \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen, const unsigned char *hash, size_t hlen,
@ -207,63 +258,74 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/** /**
* \brief Read and verify an ECDSA signature * \brief This function reads and verifies an ECDSA signature.
* *
* \param ctx ECDSA context * \param ctx The ECDSA context.
* \param hash Message hash * \param hash The message hash.
* \param hlen Size of hash * \param hlen The size of the hash.
* \param sig Signature to read and verify * \param sig The signature to read and verify.
* \param slen Size of sig * \param slen The size of \p sig.
* *
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as * bitlength of the group order, then the hash is truncated as
* prescribed by SEC1 4.1.4 step 3. * defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.4, step 3.
* *
* \return 0 if successful, * \return \c 0 on success,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid, * #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
* MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if the signature is * #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
* valid but its actual length is less than siglen, * signature in sig but its length is less than \p siglen,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_ERR_MPI_XXX error code * or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
* error code on failure for any other reason.
*
* \see ecp.h
*/ */
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen, const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen ); const unsigned char *sig, size_t slen );
/** /**
* \brief Generate an ECDSA keypair on the given curve * \brief This function generates an ECDSA keypair on the given curve.
* *
* \param ctx ECDSA context in which the keypair should be stored * \param ctx The ECDSA context to store the keypair in.
* \param gid Group (elliptic curve) to use. One of the various * \param gid The elliptic curve to use. One of the various
* MBEDTLS_ECP_DP_XXX macros depending on configuration. * \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
* \param f_rng RNG function * \param f_rng The RNG function.
* \param p_rng RNG parameter * \param p_rng The RNG parameter.
* *
* \return 0 on success, or a MBEDTLS_ERR_ECP_XXX code. * \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX code on
* failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/** /**
* \brief Set an ECDSA context from an EC key pair * \brief This function sets an ECDSA context from an EC key pair.
* *
* \param ctx ECDSA context to set * \param ctx The ECDSA context to set.
* \param key EC key to use * \param key The EC key to use.
* *
* \return 0 on success, or a MBEDTLS_ERR_ECP_XXX code. * \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX code on
* failure.
*
* \see ecp.h
*/ */
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ); int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
/** /**
* \brief Initialize context * \brief This function initializes an ECDSA context.
* *
* \param ctx Context to initialize * \param ctx The ECDSA context to initialize.
*/ */
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ); void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
/** /**
* \brief Free context * \brief This function frees an ECDSA context.
* *
* \param ctx Context to free * \param ctx The ECDSA context to free.
*/ */
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ); void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );

View file

@ -2,7 +2,8 @@
* \file ecjpake.h * \file ecjpake.h
* *
* \brief Elliptic curve J-PAKE * \brief Elliptic curve J-PAKE
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -45,6 +46,8 @@
#include "ecp.h" #include "ecp.h"
#include "md.h" #include "md.h"
#if !defined(MBEDTLS_ECJPAKE_ALT)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -224,17 +227,31 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
*/ */
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ); void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_ECJPAKE_ALT */
#include "ecjpake_alt.h"
#endif /* MBEDTLS_ECJPAKE_ALT */
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* \brief Checkup routine * \brief Checkup routine
* *
* \return 0 if successful, or 1 if a test failed * \return 0 if successful, or 1 if a test failed
*/ */
int mbedtls_ecjpake_self_test( int verbose ); int mbedtls_ecjpake_self_test( int verbose );
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* MBEDTLS_SELF_TEST */
#endif /* ecjpake.h */ #endif /* ecjpake.h */

View file

@ -2,7 +2,8 @@
* \file ecp.h * \file ecp.h
* *
* \brief Elliptic curves over GF(p) * \brief Elliptic curves over GF(p)
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -37,7 +38,8 @@
#define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 /**< Memory allocation failed. */ #define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 /**< Memory allocation failed. */
#define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as (ephemeral) key, failed. */ #define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as (ephemeral) key, failed. */
#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */ #define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */
#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< Signature is valid but shorter than the user-supplied length. */ #define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< The buffer contains a valid signature followed by more data. */
#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED -0x4B80 /**< ECP hardware accelerator failed. */
#if !defined(MBEDTLS_ECP_ALT) #if !defined(MBEDTLS_ECP_ALT)
/* /*

View file

@ -3,7 +3,8 @@
* *
* \brief Function declarations for alternative implementation of elliptic curve * \brief Function declarations for alternative implementation of elliptic curve
* point arithmetic. * point arithmetic.
* */
/*
* Copyright (C) 2016, ARM Limited, All Rights Reserved * Copyright (C) 2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -2,7 +2,8 @@
* \file entropy.h * \file entropy.h
* *
* \brief Entropy accumulator implementation * \brief Entropy accumulator implementation
* */
/*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -123,6 +124,7 @@ mbedtls_entropy_source_state;
*/ */
typedef struct typedef struct
{ {
int accumulator_started;
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_context accumulator; mbedtls_sha512_context accumulator;
#else #else

View file

@ -2,7 +2,8 @@
* \file entropy_poll.h * \file entropy_poll.h
* *
* \brief Platform-specific and custom entropy polling functions * \brief Platform-specific and custom entropy polling functions
* */
/*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -2,7 +2,8 @@
* \file error.h * \file error.h
* *
* \brief Error to string translation * \brief Error to string translation
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -51,23 +52,32 @@
* *
* Module Nr Codes assigned * Module Nr Codes assigned
* MPI 7 0x0002-0x0010 * MPI 7 0x0002-0x0010
* GCM 2 0x0012-0x0014 * GCM 3 0x0012-0x0014 0x0013-0x0013
* BLOWFISH 2 0x0016-0x0018 * BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
* THREADING 3 0x001A-0x001E * THREADING 3 0x001A-0x001E
* AES 2 0x0020-0x0022 * AES 4 0x0020-0x0022 0x0023-0x0025
* CAMELLIA 2 0x0024-0x0026 * CAMELLIA 3 0x0024-0x0026 0x0027-0x0027
* XTEA 1 0x0028-0x0028 * XTEA 2 0x0028-0x0028 0x0029-0x0029
* BASE64 2 0x002A-0x002C * BASE64 2 0x002A-0x002C
* OID 1 0x002E-0x002E 0x000B-0x000B * OID 1 0x002E-0x002E 0x000B-0x000B
* PADLOCK 1 0x0030-0x0030 * PADLOCK 1 0x0030-0x0030
* DES 1 0x0032-0x0032 * DES 2 0x0032-0x0032 0x0033-0x0033
* CTR_DBRG 4 0x0034-0x003A * CTR_DBRG 4 0x0034-0x003A
* ENTROPY 3 0x003C-0x0040 0x003D-0x003F * ENTROPY 3 0x003C-0x0040 0x003D-0x003F
* NET 11 0x0042-0x0052 0x0043-0x0045 * NET 11 0x0042-0x0052 0x0043-0x0045
* ASN1 7 0x0060-0x006C * ASN1 7 0x0060-0x006C
* CMAC 1 0x007A-0x007A
* PBKDF2 1 0x007C-0x007C * PBKDF2 1 0x007C-0x007C
* HMAC_DRBG 4 0x0003-0x0009 * HMAC_DRBG 4 0x0003-0x0009
* CCM 2 0x000D-0x000F * CCM 3 0x000D-0x0011
* ARC4 1 0x0019-0x0019
* MD2 1 0x002B-0x002B
* MD4 1 0x002D-0x002D
* MD5 1 0x002F-0x002F
* RIPEMD160 1 0x0031-0x0031
* SHA1 1 0x0035-0x0035
* SHA256 1 0x0037-0x0037
* SHA512 1 0x0039-0x0039
* *
* High-level module nr (3 bits - 0x0...-0x7...) * High-level module nr (3 bits - 0x0...-0x7...)
* Name ID Nr of Errors * Name ID Nr of Errors
@ -75,12 +85,12 @@
* PKCS#12 1 4 (Started from top) * PKCS#12 1 4 (Started from top)
* X509 2 20 * X509 2 20
* PKCS5 2 4 (Started from top) * PKCS5 2 4 (Started from top)
* DHM 3 9 * DHM 3 11
* PK 3 14 (Started from top) * PK 3 15 (Started from top)
* RSA 4 9 * RSA 4 11
* ECP 4 8 (Started from top) * ECP 4 9 (Started from top)
* MD 5 4 * MD 5 5
* CIPHER 6 6 * CIPHER 6 8
* SSL 6 17 (Started from top) * SSL 6 17 (Started from top)
* SSL 7 31 * SSL 7 31
* *

View file

@ -1,9 +1,16 @@
/** /**
* \file gcm.h * \file gcm.h
* *
* \brief Galois/Counter mode for 128-bit block ciphers * \brief Galois/Counter Mode (GCM) for 128-bit block ciphers, as defined
* in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
* (GCM), Natl. Inst. Stand. Technol.</em>
* *
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
*
*/
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,8 +27,9 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_GCM_H #ifndef MBEDTLS_GCM_H
#define MBEDTLS_GCM_H #define MBEDTLS_GCM_H
@ -33,46 +41,59 @@
#define MBEDTLS_GCM_DECRYPT 0 #define MBEDTLS_GCM_DECRYPT 0
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */ #define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */ #define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
#if !defined(MBEDTLS_GCM_ALT)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** /**
* \brief GCM context structure * \brief The GCM context structure.
*/ */
typedef struct { typedef struct {
mbedtls_cipher_context_t cipher_ctx;/*!< cipher context used */ mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
uint64_t HL[16]; /*!< Precalculated HTable */ uint64_t HL[16]; /*!< Precalculated HTable low. */
uint64_t HH[16]; /*!< Precalculated HTable */ uint64_t HH[16]; /*!< Precalculated HTable high. */
uint64_t len; /*!< Total data length */ uint64_t len; /*!< The total length of the encrypted data. */
uint64_t add_len; /*!< Total add length */ uint64_t add_len; /*!< The total length of the additional data. */
unsigned char base_ectr[16];/*!< First ECTR for tag */ unsigned char base_ectr[16]; /*!< The first ECTR for tag. */
unsigned char y[16]; /*!< Y working value */ unsigned char y[16]; /*!< The Y working value. */
unsigned char buf[16]; /*!< buf working value */ unsigned char buf[16]; /*!< The buf working value. */
int mode; /*!< Encrypt or Decrypt */ int mode; /*!< The operation to perform:
#MBEDTLS_GCM_ENCRYPT or
#MBEDTLS_GCM_DECRYPT. */
} }
mbedtls_gcm_context; mbedtls_gcm_context;
/** /**
* \brief Initialize GCM context (just makes references valid) * \brief This function initializes the specified GCM context,
* Makes the context ready for mbedtls_gcm_setkey() or * to make references valid, and prepares the context
* mbedtls_gcm_free(). * for mbedtls_gcm_setkey() or mbedtls_gcm_free().
* *
* \param ctx GCM context to initialize * The function does not bind the GCM context to a particular
* cipher, nor set the key. For this purpose, use
* mbedtls_gcm_setkey().
*
* \param ctx The GCM context to initialize.
*/ */
void mbedtls_gcm_init( mbedtls_gcm_context *ctx ); void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
/** /**
* \brief GCM initialization (encryption) * \brief This function associates a GCM context with a
* cipher algorithm and a key.
* *
* \param ctx GCM context to be initialized * \param ctx The GCM context to initialize.
* \param cipher cipher to use (a 128-bit block cipher) * \param cipher The 128-bit block cipher to use.
* \param key encryption key * \param key The encryption key.
* \param keybits must be 128, 192 or 256 * \param keybits The key size in bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
* *
* \return 0 if successful, or a cipher specific error code * \return \c 0 on success, or a cipher specific error code.
*/ */
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher, mbedtls_cipher_id_t cipher,
@ -80,26 +101,48 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
unsigned int keybits ); unsigned int keybits );
/** /**
* \brief GCM buffer encryption/decryption using a block cipher * \brief This function performs GCM encryption or decryption of a buffer.
* *
* \note On encryption, the output buffer can be the same as the input buffer. * \note For encryption, the output buffer can be the same as the input buffer.
* On decryption, the output buffer cannot be the same as input buffer. * For decryption, the output buffer cannot be the same as input buffer.
* If buffers overlap, the output buffer must trail at least 8 bytes * If the buffers overlap, the output buffer must trail at least 8 Bytes
* behind the input buffer. * behind the input buffer.
* *
* \param ctx GCM context * \warning When this function performs a decryption, it outputs the
* \param mode MBEDTLS_GCM_ENCRYPT or MBEDTLS_GCM_DECRYPT * authentication tag and does not verify that the data is
* \param length length of the input data * authentic. You should use this function to perform encryption
* \param iv initialization vector * only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
* \param iv_len length of IV
* \param add additional data
* \param add_len length of additional data
* \param input buffer holding the input data
* \param output buffer for holding the output data
* \param tag_len length of the tag to generate
* \param tag buffer for holding the tag
* *
* \return 0 if successful * \param ctx The GCM context to use for encryption or decryption.
* \param mode The operation to perform:
* - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
* The ciphertext is written to \p output and the
* authentication tag is written to \p tag.
* - #MBEDTLS_GCM_DECRYPT to perform decryption.
* The plaintext is written to \p output and the
* authentication tag is written to \p tag.
* Note that this mode is not recommended, because it does
* not verify the authenticity of the data. For this reason,
* you should use mbedtls_gcm_auth_decrypt() instead of
* calling this function in decryption mode.
* \param length The length of the input data, which is equal to the length
* of the output data.
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
* \param input The buffer holding the input data. Its size is \b length.
* \param output The buffer for holding the output data. It must have room
* for \b length bytes.
* \param tag_len The length of the tag to generate.
* \param tag The buffer for holding the tag.
*
* \return \c 0 if the encryption or decryption was performed
* successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
* this does not indicate that the data is authentic.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
* \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
* error code if the encryption or decryption failed.
*/ */
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
int mode, int mode,
@ -114,25 +157,31 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
unsigned char *tag ); unsigned char *tag );
/** /**
* \brief GCM buffer authenticated decryption using a block cipher * \brief This function performs a GCM authenticated decryption of a
* buffer.
* *
* \note On decryption, the output buffer cannot be the same as input buffer. * \note For decryption, the output buffer cannot be the same as input buffer.
* If buffers overlap, the output buffer must trail at least 8 bytes * If the buffers overlap, the output buffer must trail at least 8 Bytes
* behind the input buffer. * behind the input buffer.
* *
* \param ctx GCM context * \param ctx The GCM context.
* \param length length of the input data * \param length The length of the ciphertext to decrypt, which is also
* \param iv initialization vector * the length of the decrypted plaintext.
* \param iv_len length of IV * \param iv The initialization vector.
* \param add additional data * \param iv_len The length of the IV.
* \param add_len length of additional data * \param add The buffer holding the additional data.
* \param tag buffer holding the tag * \param add_len The length of the additional data.
* \param tag_len length of the tag * \param tag The buffer holding the tag to verify.
* \param input buffer holding the input data * \param tag_len The length of the tag to verify.
* \param output buffer for holding the output data * \param input The buffer holding the ciphertext. Its size is \b length.
* \param output The buffer for holding the decrypted plaintext. It must
* have room for \b length bytes.
* *
* \return 0 if successful and authenticated, * \return \c 0 if successful and authenticated.
* MBEDTLS_ERR_GCM_AUTH_FAILED if tag does not match * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
* \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
* error code if the decryption failed.
*/ */
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
size_t length, size_t length,
@ -146,16 +195,18 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
unsigned char *output ); unsigned char *output );
/** /**
* \brief Generic GCM stream start function * \brief This function starts a GCM encryption or decryption
* operation.
* *
* \param ctx GCM context * \param ctx The GCM context.
* \param mode MBEDTLS_GCM_ENCRYPT or MBEDTLS_GCM_DECRYPT * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
* \param iv initialization vector * #MBEDTLS_GCM_DECRYPT.
* \param iv_len length of IV * \param iv The initialization vector.
* \param add additional data (or NULL if length is 0) * \param iv_len The length of the IV.
* \param add_len length of additional data * \param add The buffer holding the additional data, or NULL if \p add_len is 0.
* \param add_len The length of the additional data. If 0, \p add is NULL.
* *
* \return 0 if successful * \return \c 0 on success.
*/ */
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
int mode, int mode,
@ -165,21 +216,23 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
size_t add_len ); size_t add_len );
/** /**
* \brief Generic GCM update function. Encrypts/decrypts using the * \brief This function feeds an input buffer into an ongoing GCM
* given GCM context. Expects input to be a multiple of 16 * encryption or decryption operation.
* bytes! Only the last call before mbedtls_gcm_finish() can be less
* than 16 bytes!
* *
* \note On decryption, the output buffer cannot be the same as input buffer. * ` The function expects input to be a multiple of 16
* If buffers overlap, the output buffer must trail at least 8 bytes * Bytes. Only the last call before calling
* mbedtls_gcm_finish() can be less than 16 Bytes.
*
* \note For decryption, the output buffer cannot be the same as input buffer.
* If the buffers overlap, the output buffer must trail at least 8 Bytes
* behind the input buffer. * behind the input buffer.
* *
* \param ctx GCM context * \param ctx The GCM context.
* \param length length of the input data * \param length The length of the input data. This must be a multiple of 16 except in the last call before mbedtls_gcm_finish().
* \param input buffer holding the input data * \param input The buffer holding the input data.
* \param output buffer for holding the output data * \param output The buffer for holding the output data.
* *
* \return 0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT * \return \c 0 on success, or #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/ */
int mbedtls_gcm_update( mbedtls_gcm_context *ctx, int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
size_t length, size_t length,
@ -187,31 +240,46 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
unsigned char *output ); unsigned char *output );
/** /**
* \brief Generic GCM finalisation function. Wraps up the GCM stream * \brief This function finishes the GCM operation and generates
* and generates the tag. The tag can have a maximum length of * the authentication tag.
* 16 bytes.
* *
* \param ctx GCM context * It wraps up the GCM stream, and generates the
* \param tag buffer for holding the tag * tag. The tag can have a maximum length of 16 Bytes.
* \param tag_len length of the tag to generate (must be at least 4)
* *
* \return 0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT * \param ctx The GCM context.
* \param tag The buffer for holding the tag.
* \param tag_len The length of the tag to generate. Must be at least four.
*
* \return \c 0 on success, or #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/ */
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
unsigned char *tag, unsigned char *tag,
size_t tag_len ); size_t tag_len );
/** /**
* \brief Free a GCM context and underlying cipher sub-context * \brief This function clears a GCM context and the underlying
* cipher sub-context.
* *
* \param ctx GCM context to free * \param ctx The GCM context to clear.
*/ */
void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
#ifdef __cplusplus
}
#endif
#else /* !MBEDTLS_GCM_ALT */
#include "gcm_alt.h"
#endif /* !MBEDTLS_GCM_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* \brief Checkup routine * \brief The GCM checkup routine.
* *
* \return 0 if successful, or 1 if the test failed * \return \c 0 on success, or \c 1 on failure.
*/ */
int mbedtls_gcm_self_test( int verbose ); int mbedtls_gcm_self_test( int verbose );
@ -219,4 +287,5 @@ int mbedtls_gcm_self_test( int verbose );
} }
#endif #endif
#endif /* gcm.h */ #endif /* gcm.h */

View file

@ -2,7 +2,8 @@
* \file havege.h * \file havege.h
* *
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -2,7 +2,8 @@
* \file hmac_drbg.h * \file hmac_drbg.h
* *
* \brief HMAC_DRBG (NIST SP 800-90A) * \brief HMAC_DRBG (NIST SP 800-90A)
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -28,7 +29,7 @@
#include "md.h" #include "md.h"
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h" #include "threading.h"
#endif #endif
/* /*

View file

@ -1,11 +1,12 @@
/** /**
* \file md.h * \file md.h
* *
* \brief Generic message digest wrapper * \brief The generic message-digest wrapper.
* *
* \author Adriaan de Jong <dejong@fox-it.com> * \author Adriaan de Jong <dejong@fox-it.com>
* */
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved /*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -22,22 +23,38 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of Mbed TLS (https://tls.mbed.org)
*/ */
#ifndef MBEDTLS_MD_H #ifndef MBEDTLS_MD_H
#define MBEDTLS_MD_H #define MBEDTLS_MD_H
#include <stddef.h> #include <stddef.h>
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */ #define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */ #define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */ #define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */ #define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/**
* \brief Enumeration of supported message digests
*
* \warning MD2, MD4, MD5 and SHA-1 are considered weak message digests and
* their use constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef enum { typedef enum {
MBEDTLS_MD_NONE=0, MBEDTLS_MD_NONE=0,
MBEDTLS_MD_MD2, MBEDTLS_MD_MD2,
@ -58,65 +75,79 @@ typedef enum {
#endif #endif
/** /**
* Opaque struct defined in md_internal.h * Opaque struct defined in md_internal.h.
*/ */
typedef struct mbedtls_md_info_t mbedtls_md_info_t; typedef struct mbedtls_md_info_t mbedtls_md_info_t;
/** /**
* Generic message digest context. * The generic message-digest context.
*/ */
typedef struct { typedef struct {
/** Information about the associated message digest */ /** Information about the associated message digest. */
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
/** Digest-specific context */ /** The digest-specific context. */
void *md_ctx; void *md_ctx;
/** HMAC part of the context */ /** The HMAC part of the context. */
void *hmac_ctx; void *hmac_ctx;
} mbedtls_md_context_t; } mbedtls_md_context_t;
/** /**
* \brief Returns the list of digests supported by the generic digest module. * \brief This function returns the list of digests supported by the
* generic digest module.
* *
* \return a statically allocated array of digests, the last entry * \return A statically allocated array of digests. Each element
* is 0. * in the returned list is an integer belonging to the
* message-digest enumeration #mbedtls_md_type_t.
* The last entry is 0.
*/ */
const int *mbedtls_md_list( void ); const int *mbedtls_md_list( void );
/** /**
* \brief Returns the message digest information associated with the * \brief This function returns the message-digest information
* given digest name. * associated with the given digest name.
* *
* \param md_name Name of the digest to search for. * \param md_name The name of the digest to search for.
* *
* \return The message digest information associated with md_name or * \return The message-digest information associated with \p md_name,
* NULL if not found. * or NULL if not found.
*/ */
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ); const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
/** /**
* \brief Returns the message digest information associated with the * \brief This function returns the message-digest information
* given digest type. * associated with the given digest type.
* *
* \param md_type type of digest to search for. * \param md_type The type of digest to search for.
* *
* \return The message digest information associated with md_type or * \return The message-digest information associated with \p md_type,
* NULL if not found. * or NULL if not found.
*/ */
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ); const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
/** /**
* \brief Initialize a md_context (as NONE) * \brief This function initializes a message-digest context without
* This should always be called first. * binding it to a particular message-digest algorithm.
* Prepares the context for mbedtls_md_setup() or mbedtls_md_free(). *
* This function should always be called first. It prepares the
* context for mbedtls_md_setup() for binding it to a
* message-digest algorithm.
*/ */
void mbedtls_md_init( mbedtls_md_context_t *ctx ); void mbedtls_md_init( mbedtls_md_context_t *ctx );
/** /**
* \brief Free and clear the internal structures of ctx. * \brief This function clears the internal structure of \p ctx and
* Can be called at any time after mbedtls_md_init(). * frees any embedded internal structure, but does not free
* Mandatory once mbedtls_md_setup() has been called. * \p ctx itself.
*
* If you have called mbedtls_md_setup() on \p ctx, you must
* call mbedtls_md_free() when you are no longer using the
* context.
* Calling this function if you have previously
* called mbedtls_md_init() and nothing else is optional.
* You must not call this function if you have not called
* mbedtls_md_init().
*/ */
void mbedtls_md_free( mbedtls_md_context_t *ctx ); void mbedtls_md_free( mbedtls_md_context_t *ctx );
@ -127,220 +158,288 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx );
#define MBEDTLS_DEPRECATED #define MBEDTLS_DEPRECATED
#endif #endif
/** /**
* \brief Select MD to use and allocate internal structures. * \brief This function selects the message digest algorithm to use,
* Should be called after mbedtls_md_init() or mbedtls_md_free(). * and allocates internal structures.
*
* It should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later. * Makes it necessary to call mbedtls_md_free() later.
* *
* \deprecated Superseded by mbedtls_md_setup() in 2.0.0 * \deprecated Superseded by mbedtls_md_setup() in 2.0.0
* *
* \param ctx Context to set up. * \param ctx The context to set up.
* \param md_info Message digest to use. * \param md_info The information structure of the message-digest algorithm
* to use.
* *
* \returns \c 0 on success, * \returns \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure, * #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
* \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure. * #MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
*/ */
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED; int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED #undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_DEPRECATED_REMOVED */
/** /**
* \brief Select MD to use and allocate internal structures. * \brief This function selects the message digest algorithm to use,
* Should be called after mbedtls_md_init() or mbedtls_md_free(). * and allocates internal structures.
* Makes it necessary to call mbedtls_md_free() later.
* *
* \param ctx Context to set up. * It should be called after mbedtls_md_init() or
* \param md_info Message digest to use. * mbedtls_md_free(). Makes it necessary to call
* \param hmac 0 to save some memory if HMAC will not be used, * mbedtls_md_free() later.
* non-zero is HMAC is going to be used with this context. *
* \param ctx The context to set up.
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param hmac <ul><li>0: HMAC is not used. Saves some memory.</li>
* <li>non-zero: HMAC is used with this context.</li></ul>
* *
* \returns \c 0 on success, * \returns \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure, * #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure, or
* \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure. * #MBEDTLS_ERR_MD_ALLOC_FAILED on memory allocation failure.
*/ */
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ); int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/** /**
* \brief Clone the state of an MD context * \brief This function clones the state of an message-digest
* context.
* *
* \note The two contexts must have been setup to the same type * \note You must call mbedtls_md_setup() on \c dst before calling
* (cloning from SHA-256 to SHA-512 make no sense). * this function.
* *
* \warning Only clones the MD state, not the HMAC state! (for now) * \note The two contexts must have the same type,
* for example, both are SHA-256.
* *
* \param dst The destination context * \warning This function clones the message-digest state, not the
* \param src The context to be cloned * HMAC state.
*
* \param dst The destination context.
* \param src The context to be cloned.
* *
* \return \c 0 on success, * \return \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure. * #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure.
*/ */
int mbedtls_md_clone( mbedtls_md_context_t *dst, int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src ); const mbedtls_md_context_t *src );
/** /**
* \brief Returns the size of the message digest output. * \brief This function extracts the message-digest size from the
* message-digest information structure.
* *
* \param md_info message digest info * \param md_info The information structure of the message-digest algorithm
* to use.
* *
* \return size of the message digest output in bytes. * \return The size of the message-digest output in Bytes.
*/ */
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ); unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info );
/** /**
* \brief Returns the type of the message digest output. * \brief This function extracts the message-digest type from the
* message-digest information structure.
* *
* \param md_info message digest info * \param md_info The information structure of the message-digest algorithm
* to use.
* *
* \return type of the message digest output. * \return The type of the message digest.
*/ */
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ); mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info );
/** /**
* \brief Returns the name of the message digest output. * \brief This function extracts the message-digest name from the
* message-digest information structure.
* *
* \param md_info message digest info * \param md_info The information structure of the message-digest algorithm
* to use.
* *
* \return name of the message digest output. * \return The name of the message digest.
*/ */
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ); const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
/** /**
* \brief Prepare the context to digest a new message. * \brief This function starts a message-digest computation.
* Generally called after mbedtls_md_setup() or mbedtls_md_finish().
* Followed by mbedtls_md_update().
* *
* \param ctx generic message digest context. * You must call this function after setting up the context
* with mbedtls_md_setup(), and before passing data with
* mbedtls_md_update().
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The generic message-digest context.
* verification fails. *
* \returns \c 0 on success, #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md_starts( mbedtls_md_context_t *ctx ); int mbedtls_md_starts( mbedtls_md_context_t *ctx );
/** /**
* \brief Generic message digest process buffer * \brief This function feeds an input buffer into an ongoing
* Called between mbedtls_md_starts() and mbedtls_md_finish(). * message-digest computation.
* May be called repeatedly.
* *
* \param ctx Generic message digest context * You must call mbedtls_md_starts() before calling this
* \param input buffer holding the datal * function. You may call this function multiple times.
* \param ilen length of the input data * Afterwards, call mbedtls_md_finish().
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The generic message-digest context.
* verification fails. * \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \returns \c 0 on success, #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ); int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
/** /**
* \brief Generic message digest final digest * \brief This function finishes the digest operation,
* Called after mbedtls_md_update(). * and writes the result to the output buffer.
* Usually followed by mbedtls_md_free() or mbedtls_md_starts().
* *
* \param ctx Generic message digest context * Call this function after a call to mbedtls_md_starts(),
* \param output Generic message digest checksum result * followed by any number of calls to mbedtls_md_update().
* Afterwards, you may either clear the context with
* mbedtls_md_free(), or call mbedtls_md_starts() to reuse
* the context for another digest operation with the same
* algorithm.
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The generic message-digest context.
* verification fails. * \param output The buffer for the generic message-digest checksum result.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ); int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
/** /**
* \brief Output = message_digest( input buffer ) * \brief This function calculates the message-digest of a buffer,
* with respect to a configurable message-digest algorithm
* in a single call.
* *
* \param md_info message digest info * The result is calculated as
* \param input buffer holding the data * Output = message_digest(input buffer).
* \param ilen length of the input data
* \param output Generic message digest checksum result
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param md_info The information structure of the message-digest algorithm
* verification fails. * to use.
* \param input The buffer holding the data.
* \param ilen The length of the input data.
* \param output The generic message-digest checksum result.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output ); unsigned char *output );
#if defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_FS_IO)
/** /**
* \brief Output = message_digest( file contents ) * \brief This function calculates the message-digest checksum
* result of the contents of the provided file.
* *
* \param md_info message digest info * The result is calculated as
* \param path input file name * Output = message_digest(file contents).
* \param output generic message digest checksum result
* *
* \return 0 if successful, * \param md_info The information structure of the message-digest algorithm
* MBEDTLS_ERR_MD_FILE_IO_ERROR if file input failed, * to use.
* MBEDTLS_ERR_MD_BAD_INPUT_DATA if md_info was NULL. * \param path The input file name.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success,
* #MBEDTLS_ERR_MD_FILE_IO_ERROR if file input failed, or
* #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
*/ */
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output ); unsigned char *output );
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */
/** /**
* \brief Set HMAC key and prepare to authenticate a new message. * \brief This function sets the HMAC key and prepares to
* Usually called after mbedtls_md_setup() or mbedtls_md_hmac_finish(). * authenticate a new message.
* *
* \param ctx HMAC context * Call this function after mbedtls_md_setup(), to use
* \param key HMAC secret key * the MD context for an HMAC calculation, then call
* \param keylen length of the HMAC key in bytes * mbedtls_md_hmac_update() to provide the input data, and
* mbedtls_md_hmac_finish() to get the HMAC value.
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The message digest context containing an embedded HMAC
* verification fails. * context.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC key in Bytes.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen ); size_t keylen );
/** /**
* \brief Generic HMAC process buffer. * \brief This function feeds an input buffer into an ongoing HMAC
* Called between mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset() * computation.
* and mbedtls_md_hmac_finish().
* May be called repeatedly.
* *
* \param ctx HMAC context * Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
* \param input buffer holding the data * before calling this function.
* \param ilen length of the input data * You may call this function multiple times to pass the
* input piecewise.
* Afterwards, call mbedtls_md_hmac_finish().
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The message digest context containing an embedded HMAC
* verification fails. * context.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
size_t ilen ); size_t ilen );
/** /**
* \brief Output HMAC. * \brief This function finishes the HMAC operation, and writes
* Called after mbedtls_md_hmac_update(). * the result to the output buffer.
* Usually followed by mbedtls_md_hmac_reset(),
* mbedtls_md_hmac_starts(), or mbedtls_md_free().
* *
* \param ctx HMAC context * Call this function after mbedtls_md_hmac_starts() and
* \param output Generic HMAC checksum result * mbedtls_md_hmac_update() to get the HMAC value. Afterwards
* you may either call mbedtls_md_free() to clear the context,
* or call mbedtls_md_hmac_reset() to reuse the context with
* the same HMAC key.
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The message digest context containing an embedded HMAC
* verification fails. * context.
* \param output The generic HMAC checksum result.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output); int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
/** /**
* \brief Prepare to authenticate a new message with the same key. * \brief This function prepares to authenticate a new message with
* Called after mbedtls_md_hmac_finish() and before * the same key as the previous HMAC operation.
* mbedtls_md_hmac_update().
* *
* \param ctx HMAC context to be reset * You may call this function after mbedtls_md_hmac_finish().
* Afterwards call mbedtls_md_hmac_update() to pass the new
* input.
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * \param ctx The message digest context containing an embedded HMAC
* verification fails. * context.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ); int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
/** /**
* \brief Output = Generic_HMAC( hmac key, input buffer ) * \brief This function calculates the full generic HMAC
* on the input buffer with the provided key.
* *
* \param md_info message digest info * The function allocates the context, performs the
* \param key HMAC secret key * calculation, and frees the context.
* \param keylen length of the HMAC key in bytes
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic HMAC-result
* *
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter * The HMAC result is calculated as
* verification fails. * output = generic HMAC(hmac key, input buffer).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC secret key in Bytes.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
* \param output The generic HMAC result.
*
* \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
* parameter verification fails.
*/ */
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen, const unsigned char *input, size_t ilen,

View file

@ -3,6 +3,11 @@
* *
* \brief MD2 message digest algorithm (hash function) * \brief MD2 message digest algorithm (hash function)
* *
* \warning MD2 is considered a weak message digest and its use constitutes a
* security risk. We recommend considering stronger message digests
* instead.
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -21,6 +26,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*
*/ */
#ifndef MBEDTLS_MD2_H #ifndef MBEDTLS_MD2_H
#define MBEDTLS_MD2_H #define MBEDTLS_MD2_H
@ -33,6 +39,8 @@
#include <stddef.h> #include <stddef.h>
#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED -0x002B /**< MD2 hardware accelerator failed */
#if !defined(MBEDTLS_MD2_ALT) #if !defined(MBEDTLS_MD2_ALT)
// Regular implementation // Regular implementation
// //
@ -43,6 +51,11 @@ extern "C" {
/** /**
* \brief MD2 context structure * \brief MD2 context structure
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
typedef struct typedef struct
{ {
@ -57,6 +70,11 @@ mbedtls_md2_context;
* \brief Initialize MD2 context * \brief Initialize MD2 context
* *
* \param ctx MD2 context to be initialized * \param ctx MD2 context to be initialized
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md2_init( mbedtls_md2_context *ctx ); void mbedtls_md2_init( mbedtls_md2_context *ctx );
@ -64,6 +82,11 @@ void mbedtls_md2_init( mbedtls_md2_context *ctx );
* \brief Clear MD2 context * \brief Clear MD2 context
* *
* \param ctx MD2 context to be cleared * \param ctx MD2 context to be cleared
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md2_free( mbedtls_md2_context *ctx ); void mbedtls_md2_free( mbedtls_md2_context *ctx );
@ -72,6 +95,11 @@ void mbedtls_md2_free( mbedtls_md2_context *ctx );
* *
* \param dst The destination context * \param dst The destination context
* \param src The context to be cloned * \param src The context to be cloned
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md2_clone( mbedtls_md2_context *dst, void mbedtls_md2_clone( mbedtls_md2_context *dst,
const mbedtls_md2_context *src ); const mbedtls_md2_context *src );
@ -80,8 +108,15 @@ void mbedtls_md2_clone( mbedtls_md2_context *dst,
* \brief MD2 context setup * \brief MD2 context setup
* *
* \param ctx context to be initialized * \param ctx context to be initialized
*
* \return 0 if successful
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md2_starts( mbedtls_md2_context *ctx ); int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx );
/** /**
* \brief MD2 process buffer * \brief MD2 process buffer
@ -89,16 +124,118 @@ void mbedtls_md2_starts( mbedtls_md2_context *ctx );
* \param ctx MD2 context * \param ctx MD2 context
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
*
* \return 0 if successful
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, size_t ilen ); int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen );
/** /**
* \brief MD2 final digest * \brief MD2 final digest
* *
* \param ctx MD2 context * \param ctx MD2 context
* \param output MD2 checksum result * \param output MD2 checksum result
*
* \return 0 if successful
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] ); int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
unsigned char output[16] );
/**
* \brief MD2 process data block (internal use only)
*
* \param ctx MD2 context
*
* \return 0 if successful
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_internal_md2_process( mbedtls_md2_context *ctx );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief MD2 context setup
*
* \deprecated Superseded by mbedtls_md2_starts_ret() in 2.7.0
*
* \param ctx context to be initialized
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2_starts( mbedtls_md2_context *ctx );
/**
* \brief MD2 process buffer
*
* \deprecated Superseded by mbedtls_md2_update_ret() in 2.7.0
*
* \param ctx MD2 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2_update( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD2 final digest
*
* \deprecated Superseded by mbedtls_md2_finish_ret() in 2.7.0
*
* \param ctx MD2 context
* \param output MD2 checksum result
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2_finish( mbedtls_md2_context *ctx,
unsigned char output[16] );
/**
* \brief MD2 process data block (internal use only)
*
* \deprecated Superseded by mbedtls_internal_md2_process() in 2.7.0
*
* \param ctx MD2 context
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -118,19 +255,55 @@ extern "C" {
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
* \param output MD2 checksum result * \param output MD2 checksum result
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md2( const unsigned char *input, size_t ilen, unsigned char output[16] ); int mbedtls_md2_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Output = MD2( input buffer )
*
* \deprecated Superseded by mbedtls_md2_ret() in 2.7.0
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD2 checksum result
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/** /**
* \brief Checkup routine * \brief Checkup routine
* *
* \return 0 if successful, or 1 if the test failed * \return 0 if successful, or 1 if the test failed
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
int mbedtls_md2_self_test( int verbose ); int mbedtls_md2_self_test( int verbose );
/* Internal use */
void mbedtls_md2_process( mbedtls_md2_context *ctx );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -3,6 +3,11 @@
* *
* \brief MD4 message digest algorithm (hash function) * \brief MD4 message digest algorithm (hash function)
* *
* \warning MD4 is considered a weak message digest and its use constitutes a
* security risk. We recommend considering stronger message digests
* instead.
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -21,6 +26,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*
*/ */
#ifndef MBEDTLS_MD4_H #ifndef MBEDTLS_MD4_H
#define MBEDTLS_MD4_H #define MBEDTLS_MD4_H
@ -34,6 +40,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED -0x002D /**< MD4 hardware accelerator failed */
#if !defined(MBEDTLS_MD4_ALT) #if !defined(MBEDTLS_MD4_ALT)
// Regular implementation // Regular implementation
// //
@ -44,6 +52,11 @@ extern "C" {
/** /**
* \brief MD4 context structure * \brief MD4 context structure
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
typedef struct typedef struct
{ {
@ -57,6 +70,11 @@ mbedtls_md4_context;
* \brief Initialize MD4 context * \brief Initialize MD4 context
* *
* \param ctx MD4 context to be initialized * \param ctx MD4 context to be initialized
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md4_init( mbedtls_md4_context *ctx ); void mbedtls_md4_init( mbedtls_md4_context *ctx );
@ -64,6 +82,11 @@ void mbedtls_md4_init( mbedtls_md4_context *ctx );
* \brief Clear MD4 context * \brief Clear MD4 context
* *
* \param ctx MD4 context to be cleared * \param ctx MD4 context to be cleared
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md4_free( mbedtls_md4_context *ctx ); void mbedtls_md4_free( mbedtls_md4_context *ctx );
@ -72,6 +95,11 @@ void mbedtls_md4_free( mbedtls_md4_context *ctx );
* *
* \param dst The destination context * \param dst The destination context
* \param src The context to be cloned * \param src The context to be cloned
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md4_clone( mbedtls_md4_context *dst, void mbedtls_md4_clone( mbedtls_md4_context *dst,
const mbedtls_md4_context *src ); const mbedtls_md4_context *src );
@ -80,8 +108,14 @@ void mbedtls_md4_clone( mbedtls_md4_context *dst,
* \brief MD4 context setup * \brief MD4 context setup
* *
* \param ctx context to be initialized * \param ctx context to be initialized
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*/ */
void mbedtls_md4_starts( mbedtls_md4_context *ctx ); int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx );
/** /**
* \brief MD4 process buffer * \brief MD4 process buffer
@ -89,16 +123,122 @@ void mbedtls_md4_starts( mbedtls_md4_context *ctx );
* \param ctx MD4 context * \param ctx MD4 context
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, size_t ilen ); int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen );
/** /**
* \brief MD4 final digest * \brief MD4 final digest
* *
* \param ctx MD4 context * \param ctx MD4 context
* \param output MD4 checksum result * \param output MD4 checksum result
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] ); int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
unsigned char output[16] );
/**
* \brief MD4 process data block (internal use only)
*
* \param ctx MD4 context
* \param data buffer holding one block of data
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief MD4 context setup
*
* \deprecated Superseded by mbedtls_md4_starts_ret() in 2.7.0
*
* \param ctx context to be initialized
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4_starts( mbedtls_md4_context *ctx );
/**
* \brief MD4 process buffer
*
* \deprecated Superseded by mbedtls_md4_update_ret() in 2.7.0
*
* \param ctx MD4 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4_update( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD4 final digest
*
* \deprecated Superseded by mbedtls_md4_finish_ret() in 2.7.0
*
* \param ctx MD4 context
* \param output MD4 checksum result
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4_finish( mbedtls_md4_context *ctx,
unsigned char output[16] );
/**
* \brief MD4 process data block (internal use only)
*
* \deprecated Superseded by mbedtls_internal_md4_process() in 2.7.0
*
* \param ctx MD4 context
* \param data buffer holding one block of data
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -118,19 +258,57 @@ extern "C" {
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
* \param output MD4 checksum result * \param output MD4 checksum result
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] ); int mbedtls_md4_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Output = MD4( input buffer )
*
* \deprecated Superseded by mbedtls_md4_ret() in 2.7.0
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD4 checksum result
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/** /**
* \brief Checkup routine * \brief Checkup routine
* *
* \return 0 if successful, or 1 if the test failed * \return 0 if successful, or 1 if the test failed
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
int mbedtls_md4_self_test( int verbose ); int mbedtls_md4_self_test( int verbose );
/* Internal use */
void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -3,6 +3,11 @@
* *
* \brief MD5 message digest algorithm (hash function) * \brief MD5 message digest algorithm (hash function)
* *
* \warning MD5 is considered a weak message digest and its use constitutes a
* security risk. We recommend considering stronger message
* digests instead.
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -34,6 +39,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */
#if !defined(MBEDTLS_MD5_ALT) #if !defined(MBEDTLS_MD5_ALT)
// Regular implementation // Regular implementation
// //
@ -44,6 +51,11 @@ extern "C" {
/** /**
* \brief MD5 context structure * \brief MD5 context structure
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
typedef struct typedef struct
{ {
@ -57,6 +69,11 @@ mbedtls_md5_context;
* \brief Initialize MD5 context * \brief Initialize MD5 context
* *
* \param ctx MD5 context to be initialized * \param ctx MD5 context to be initialized
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md5_init( mbedtls_md5_context *ctx ); void mbedtls_md5_init( mbedtls_md5_context *ctx );
@ -64,6 +81,11 @@ void mbedtls_md5_init( mbedtls_md5_context *ctx );
* \brief Clear MD5 context * \brief Clear MD5 context
* *
* \param ctx MD5 context to be cleared * \param ctx MD5 context to be cleared
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md5_free( mbedtls_md5_context *ctx ); void mbedtls_md5_free( mbedtls_md5_context *ctx );
@ -72,6 +94,11 @@ void mbedtls_md5_free( mbedtls_md5_context *ctx );
* *
* \param dst The destination context * \param dst The destination context
* \param src The context to be cloned * \param src The context to be cloned
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md5_clone( mbedtls_md5_context *dst, void mbedtls_md5_clone( mbedtls_md5_context *dst,
const mbedtls_md5_context *src ); const mbedtls_md5_context *src );
@ -80,8 +107,15 @@ void mbedtls_md5_clone( mbedtls_md5_context *dst,
* \brief MD5 context setup * \brief MD5 context setup
* *
* \param ctx context to be initialized * \param ctx context to be initialized
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md5_starts( mbedtls_md5_context *ctx ); int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx );
/** /**
* \brief MD5 process buffer * \brief MD5 process buffer
@ -89,19 +123,122 @@ void mbedtls_md5_starts( mbedtls_md5_context *ctx );
* \param ctx MD5 context * \param ctx MD5 context
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen ); int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen );
/** /**
* \brief MD5 final digest * \brief MD5 final digest
* *
* \param ctx MD5 context * \param ctx MD5 context
* \param output MD5 checksum result * \param output MD5 checksum result
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ); int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
unsigned char output[16] );
/* Internal use */ /**
void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ); * \brief MD5 process data block (internal use only)
*
* \param ctx MD5 context
* \param data buffer holding one block of data
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief MD5 context setup
*
* \deprecated Superseded by mbedtls_md5_starts_ret() in 2.7.0
*
* \param ctx context to be initialized
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \deprecated Superseded by mbedtls_md5_update_ret() in 2.7.0
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD5 final digest
*
* \deprecated Superseded by mbedtls_md5_finish_ret() in 2.7.0
*
* \param ctx MD5 context
* \param output MD5 checksum result
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx,
unsigned char output[16] );
/**
* \brief MD5 process data block (internal use only)
*
* \deprecated Superseded by mbedtls_internal_md5_process() in 2.7.0
*
* \param ctx MD5 context
* \param data buffer holding one block of data
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -121,13 +258,54 @@ extern "C" {
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
* \param output MD5 checksum result * \param output MD5 checksum result
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] ); int mbedtls_md5_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Output = MD5( input buffer )
*
* \deprecated Superseded by mbedtls_md5_ret() in 2.7.0
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/** /**
* \brief Checkup routine * \brief Checkup routine
* *
* \return 0 if successful, or 1 if the test failed * \return 0 if successful, or 1 if the test failed
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/ */
int mbedtls_md5_self_test( int verbose ); int mbedtls_md5_self_test( int verbose );

View file

@ -6,7 +6,8 @@
* \warning This in an internal header. Do not include directly. * \warning This in an internal header. Do not include directly.
* *
* \author Adriaan de Jong <dejong@fox-it.com> * \author Adriaan de Jong <dejong@fox-it.com>
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -60,16 +61,16 @@ struct mbedtls_md_info_t
int block_size; int block_size;
/** Digest initialisation function */ /** Digest initialisation function */
void (*starts_func)( void *ctx ); int (*starts_func)( void *ctx );
/** Digest update function */ /** Digest update function */
void (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); int (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
/** Digest finalisation function */ /** Digest finalisation function */
void (*finish_func)( void *ctx, unsigned char *output ); int (*finish_func)( void *ctx, unsigned char *output );
/** Generic digest function */ /** Generic digest function */
void (*digest_func)( const unsigned char *input, size_t ilen, int (*digest_func)( const unsigned char *input, size_t ilen,
unsigned char *output ); unsigned char *output );
/** Allocate a new context */ /** Allocate a new context */
@ -82,7 +83,7 @@ struct mbedtls_md_info_t
void (*clone_func)( void *dst, const void *src ); void (*clone_func)( void *dst, const void *src );
/** Internal use only */ /** Internal use only */
void (*process_func)( void *ctx, const unsigned char *input ); int (*process_func)( void *ctx, const unsigned char *input );
}; };
#if defined(MBEDTLS_MD2_C) #if defined(MBEDTLS_MD2_C)

View file

@ -2,7 +2,8 @@
* \file memory_buffer_alloc.h * \file memory_buffer_alloc.h
* *
* \brief Buffer-based memory allocator * \brief Buffer-based memory allocator
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -1,8 +1,11 @@
/** /**
* \file net.h * \file net.h
* *
* \brief Deprecated header file that includes mbedtls/net_sockets.h * \brief Deprecated header file that includes net_sockets.h
* *
* \deprecated Superseded by mbedtls/net_sockets.h
*/
/*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -21,12 +24,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*
* \deprecated Superseded by mbedtls/net_sockets.h
*/ */
#if !defined(MBEDTLS_DEPRECATED_REMOVED) #if !defined(MBEDTLS_DEPRECATED_REMOVED)
#include "mbedtls/net_sockets.h" #include "net_sockets.h"
#if defined(MBEDTLS_DEPRECATED_WARNING) #if defined(MBEDTLS_DEPRECATED_WARNING)
#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" #warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
#endif /* MBEDTLS_DEPRECATED_WARNING */ #endif /* MBEDTLS_DEPRECATED_WARNING */

View file

@ -2,7 +2,8 @@
* \file net_sockets.h * \file net_sockets.h
* *
* \brief Network communication functions * \brief Network communication functions
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -119,9 +120,10 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
* *
* \param bind_ctx Relevant socket * \param bind_ctx Relevant socket
* \param client_ctx Will contain the connected client socket * \param client_ctx Will contain the connected client socket
* \param client_ip Will contain the client IP address * \param client_ip Will contain the client IP address, can be NULL
* \param buf_size Size of the client_ip buffer * \param buf_size Size of the client_ip buffer
* \param ip_len Will receive the size of the client IP written * \param ip_len Will receive the size of the client IP written,
* can be NULL if client_ip is null
* *
* \return 0 if successful, or * \return 0 if successful, or
* MBEDTLS_ERR_NET_ACCEPT_FAILED, or * MBEDTLS_ERR_NET_ACCEPT_FAILED, or

View file

@ -2,7 +2,8 @@
* \file oid.h * \file oid.h
* *
* \brief Object Identifier (OID) database * \brief Object Identifier (OID) database
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -229,6 +230,14 @@
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */ #define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
/* /*
* Encryption algorithms * Encryption algorithms
*/ */
@ -515,6 +524,16 @@ int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/ */
int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg ); int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg );
/**
* \brief Translate hmac algorithm OID into md_type
*
* \param oid OID to use
* \param md_hmac place to store message hmac algorithm
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
#endif /* MBEDTLS_MD_C */ #endif /* MBEDTLS_MD_C */
/** /**

View file

@ -3,7 +3,8 @@
* *
* \brief VIA PadLock ACE for HW encryption/decryption supported by some * \brief VIA PadLock ACE for HW encryption/decryption supported by some
* processors * processors
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -2,7 +2,8 @@
* \file pem.h * \file pem.h
* *
* \brief Privacy Enhanced Mail (PEM) decoding * \brief Privacy Enhanced Mail (PEM) decoding
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -2,7 +2,8 @@
* \file pk.h * \file pk.h
* *
* \brief Public Key abstraction layer * \brief Public Key abstraction layer
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *
@ -64,7 +65,8 @@
#define MBEDTLS_ERR_PK_INVALID_ALG -0x3A80 /**< The algorithm tag or value is invalid. */ #define MBEDTLS_ERR_PK_INVALID_ALG -0x3A80 /**< The algorithm tag or value is invalid. */
#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */ #define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */
#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */ #define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */
#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The signature is valid but its length is less than expected. */ #define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The buffer contains a valid signature followed by more data. */
#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -269,8 +271,8 @@ int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
* \param sig_len Signature length * \param sig_len Signature length
* *
* \return 0 on success (signature is valid), * \return 0 on success (signature is valid),
* MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if the signature is * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* valid but its actual length is less than sig_len, * signature in sig but its length is less than \p siglen,
* or a specific error code. * or a specific error code.
* *
* \note For RSA keys, the default padding type is PKCS#1 v1.5. * \note For RSA keys, the default padding type is PKCS#1 v1.5.
@ -300,10 +302,10 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
* \param sig_len Signature length * \param sig_len Signature length
* *
* \return 0 on success (signature is valid), * \return 0 on success (signature is valid),
* MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be * #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be
* used for this type of signatures, * used for this type of signatures,
* MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if the signature is * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* valid but its actual length is less than sig_len, * signature in sig but its length is less than \p siglen,
* or a specific error code. * or a specific error code.
* *
* \note If hash_len is 0, then the length associated with md_alg * \note If hash_len is 0, then the length associated with md_alg

View file

@ -1,8 +1,9 @@
/** /**
* \file pk.h * \file pk_internal.h
* *
* \brief Public Key abstraction layer: wrapper functions * \brief Public Key abstraction layer: wrapper functions
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

View file

@ -4,7 +4,8 @@
* \brief Wrapper for PKCS#11 library libpkcs11-helper * \brief Wrapper for PKCS#11 library libpkcs11-helper
* *
* \author Adriaan de Jong <dejong@fox-it.com> * \author Adriaan de Jong <dejong@fox-it.com>
* */
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
* *

Some files were not shown because too many files have changed in this diff Show more